diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index dcefcc2e..f081cf2f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -31,7 +31,7 @@ These instructions define how GitHub Copilot should assist with this project. Th ## File Structure -```txt +```plaintext .azuredevops/ # Azure DevOps pipeline configuration and policy files. .github/ # GitHub Actions workflow files and linter configuration files. .nuget/ # NuGet package configuration files. @@ -47,6 +47,7 @@ Texdiag/ # CLI tool for diagnosing and validating DDS texture files. DDSTextureLoader/ # Standalone version of the DDS texture loader for Direct3D 9/11/12. ScreenGrab/ # Standalone version of the screenshot capture utility for Direct3D 9/11/12. WICTextureLoader/ # Standalone version of the WIC texture loader for Direct3D 9/11/12. +skills/ # Published CoPilot skills for use by developers. Tests/ # Tests are designed to be cloned from a separate repository at this location. wiki/ # Local clone of the GitHub wiki documentation repository. ``` @@ -299,30 +300,4 @@ When reviewing documentation, do the following: ## Release Process -1. Ensure all changes are merged into the `main` branch and that all tests pass. -2. Git pull the local repository to ensure it is up to date with the `main` branch. -3. Run the PowerShell script `build\preparerelease.ps1` which will generate a topic branch for the release, update the version number in `CMakeLists.txt`, the `README.md` file, the release notes in the nuspec files, and create a stub in the `CHANGELOG.md` file for the new release. -4. Edit the `CHANGELOG.md` file to update it with a summary of changes. -5. Submit the topic branch for review and merge into `main` once approved. Allow the GitHub Actions workflows and the Azure DevOps pipelines to complete successfully before proceeding. -6. Run the PowerShell script `build\completerelease.ps1` which will set a tag on the project repo and the test repo, and create a release on GitHub with the release notes from `CHANGELOG.md`. Ensure you have set up GPG signing for your GitHub account so that the tags will be verified. -7. Git pull the local repository to ensure it is up to date with the `main` branch. Be sure to include `--tags`. -8. Push the `main` branch to the MSCodeHub mirror repository. Be sure to include `--tags`. -9. Create a PR on MSCodeHub from the `main` branch to the `release` branch. -10. Merge the PR on MSCodeHub to update the release branch, which will trigger the Azure DevOps pipeline to build signed binaries and the NuGet packages. -11. Run the PowerShell script `build\downloadartifacts.ps1` to download the signed binaries from the Azure DevOps pipeline artifacts. -12. Edit the GitHub release and upload the signed binaries to the release assets. -13. Download the GitHub source .zip archive from the release. Unzip and compare to the local repo to ensure it matches — keep in mind there may be some CR/LF differences. Run minisign on the .zip to generate a signature file, and upload the signature file to the release assets. -14. Validate the NuGet packages with by pushing the NuGet packages to a local Packages Source folder, updating the NuGet packages from that folder, and then build the project. -15. Run the PowerShell script `build\promotenuget.ps1` with the `-Release` parameter to promote the version to the Release view on the project-scoped ADO feed. -16. Run the MSCodeHub pipeline to publish the NuGet packages to nuget.org. The pipeline will automatically push the most recent package promoted to the Release view to nuget.org. -17. Git pull a local repository of VCPKG to `d:\vcpkg` in sync with the `main` branch of the VCPKG repository. -18. Run the PowerShell script `build\updatevcpkg.ps1` to update the DirectXTex port in VCPKG with the new release version. This will edit the files in `ports\directxtex`. -19. Test the VCPKG port using all appropriate triplets and features. -20. Run `.\vcpkg --x-add-version directxtex` to update the VCPKG versioning history. -21. Submit a PR to the VCPKG repository to update the DirectXTex port back to the main GitHub repo. The PR will be reviewed and merged by the VCPKG maintainers. -22. If relevant changes were made to the `texassemble`, `texconv` or `texdiag` tools, update the winget manifests for those tools in the `winget` repository. -- Git pull a local repository to `D:\winget-pkgs` in sync with the `master` branch of the WinGet repository. -- Run the PowerShell script `build\updatewinget.ps1` to update the winget manifests for the tools with the new release version. -- Submit a PR to the `winget` repository to update the manifests for each tool — they must be done as distinct PRs. The PRs will be reviewed and merged by the winget maintainers. - -> When fully completed, be sure to update the GitHub release with links to the matching NuGet packages, the VCPKG port, and the winget manifests for the tools. +The release process is documented in the [release skill](.github/skills/release/SKILL.md). Invoke the `release` skill for step-by-step guidance when performing a release. diff --git a/.github/skills/release/SKILL.md b/.github/skills/release/SKILL.md new file mode 100644 index 00000000..ee0f4b85 --- /dev/null +++ b/.github/skills/release/SKILL.md @@ -0,0 +1,83 @@ +--- +name: Release Process +description: Guide for performing the DirectXTex release process. Use this skill when asked to help with releasing a new version, publishing packages, or updating ports. +--- + +# Release Process + +## Prerequisites + +- All changes merged into the `main` branch with all tests passing. +- GPG signing configured for your GitHub account (for verified tags). +- Access to the MSCodeHub mirror repository and Azure DevOps pipelines. +- Local repositories: + - VCPKG at `d:\vcpkg` (synced with `main` branch) + - WinGet at `D:\winget-pkgs` (synced with `master` branch, only if tool updates needed) +- PATs will be needed for scripts that access GitHub and ADO. + + +## Steps + +### Phase 1: Prepare Release + +1. Git pull the local repository to ensure it is up to date with the `main` branch. +2. Run the PowerShell script `build\preparerelease.ps1` which will generate a topic branch for the release, update the version number in `CMakeLists.txt`, the `README.md` file, the release notes in the nuspec files, and create a stub in the `CHANGELOG.md` file for the new release. +3. Edit the `CHANGELOG.md` file to update it with a summary of changes. +4. Submit the topic branch for review and merge into `main` once approved. Allow the GitHub Actions workflows and the Azure DevOps pipelines to complete successfully before proceeding. + +### Phase 2: Tag and Create GitHub Release + +5. Run the PowerShell script `build\completerelease.ps1` which will set a tag on the project repo and the test repo, and create a release on GitHub with the release notes from `CHANGELOG.md`. Ensure you have set up GPG signing for your GitHub account so that the tags will be verified. +6. Git pull the local repository to ensure it is up to date with the `main` branch. Be sure to include `--tags`. + +### Phase 3: MSCodeHub and Signed Binaries + +7. Push the `main` branch to the MSCodeHub mirror repository. Be sure to include `--tags`. +8. Create a PR on MSCodeHub from the `main` branch to the `release` branch. +9. Merge the PR on MSCodeHub to update the release branch, which will trigger the Azure DevOps pipeline to build signed binaries and the NuGet packages. +10. Run the PowerShell script `build\downloadbuild.ps1` to download the signed binaries from the Azure DevOps pipeline artifacts. +11. Edit the GitHub release and upload the signed binaries to the release assets. + +### Phase 4: Source Archive Signing + +12. Download the GitHub source .zip archive from the release. Unzip and compare to the local repo to ensure it matches — keep in mind there may be some CR/LF differences. +13. Run minisign on the .zip to generate a signature file, and upload the signature file to the release assets. + +### Phase 5: NuGet Validation and Publishing + +14. Validate the NuGet packages with by pushing the NuGet packages to a local Packages Source folder, updating the NuGet packages from that folder, and then build the project. +15. Run the PowerShell script `build\promotenuget.ps1 -Version -Release` to promote the version to the Release view on the project-scoped ADO feed. The `-Version` parameter is required and should match the NuGet package version (e.g., `2026.6.2.1`). +16. Run the MSCodeHub pipeline to publish the NuGet packages to nuget.org. The pipeline will automatically push the most recent package promoted to the Release view to nuget.org. + +### Phase 6: VCPKG Port Update + +17. Git pull a local repository of VCPKG to `d:\vcpkg` in sync with the `main` branch of the VCPKG repository. +18. Run the PowerShell script `build\updatevcpkg.ps1` to update the DirectXTex port in VCPKG with the new release version. This will edit the files in `ports\directxtex`. + If the port includes patches, review them to determine if they should be removed or updated for the new release (the `updatevcpkg.ps1` script will warn about this). +19. Test the VCPKG port using the script at `assets/vcpkgdxtex.cmd` (in this skill folder). Copy it to `d:\vcpkg` and run from there after bootstrapping VCPKG. +20. Run `.\vcpkg x-add-version directxtex` to update the VCPKG versioning history. +21. Submit a PR to the VCPKG repository to update the DirectXTex port back to the main GitHub repo. The PR will be reviewed and merged by the VCPKG maintainers. + +### Phase 7: WinGet Manifests (Conditional) + +If relevant changes were made to the `texassemble`, `texconv` or `texdiag` tools: + +22. Git pull a local repository to `D:\winget-pkgs` in sync with the `master` branch of the WinGet repository. +23. Run the PowerShell script `build\updatewinget.ps1` to update the winget manifests for the tools with the new release version. +24. Submit a PR to the `winget` repository to update the manifests for each tool — they must be done as distinct PRs. The PRs will be reviewed and merged by the winget maintainers. + +### Phase 8: Finalize + +When fully completed, be sure to update the GitHub release with links to the matching NuGet packages, the VCPKG port, and the winget manifests for the tools. + +## Key Scripts + +| Script | Purpose | +| --- | --- | +| `build\preparerelease.ps1` | Creates topic branch, updates version numbers and changelog stub | +| `build\completerelease.ps1` | Sets tags, creates GitHub release from changelog | +| `build\downloadbuild.ps1` | Downloads signed binaries from Azure DevOps | +| `build\promotenuget.ps1` | Promotes NuGet package to Release view on ADO feed | +| `build\updatevcpkg.ps1` | Updates DirectXTex VCPKG port files | +| `assets\vcpkgdxtex.cmd` | Tests VCPKG port across all triplets and features | +| `build\updatewinget.ps1` | Updates winget manifests for CLI tools | diff --git a/.github/skills/release/assets/vcpkgdxtex.cmd b/.github/skills/release/assets/vcpkgdxtex.cmd new file mode 100644 index 00000000..9c4ba779 --- /dev/null +++ b/.github/skills/release/assets/vcpkgdxtex.cmd @@ -0,0 +1,174 @@ +@set VCPKG_BINARY_SOURCES=clear +@set VCPKG_ROOT=%cd% +@if %1.==xbox. goto xbox +@if %1.==clang. goto clang +.\vcpkg install directxtex[core]:x86-windows +@if errorlevel 1 goto error +.\vcpkg install directxtex:x86-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:x86-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[dx12]:x86-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[openexr,tools]:x86-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[spectre]:x86-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:x86-windows-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:x86-windows-static-md +@if errorlevel 1 goto error +.\vcpkg install directxtex[core]:x64-windows +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:x64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[dx12]:x64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[openexr,tools]:x64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[spectre]:x64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-windows-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-windows-static-md +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-windows +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:arm64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[spectre]:arm64-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-windows-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-windows-static-md +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64ec-windows +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:arm64ec-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[spectre]:arm64ec-windows --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:x86-uwp +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-uwp +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-uwp +@if errorlevel 1 goto error +@where /Q x86_64-w64-mingw32-g++.exe +@if errorlevel 1 goto skipgcc64 +.\vcpkg install directxtex:x64-mingw-dynamic +@if errorlevel 1 goto error +.\vcpkg install directxtex[dx12]:x64-mingw-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:x64-mingw-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-mingw-static +@if errorlevel 1 goto error +.\vcpkg install directxtex[dx12]:x64-mingw-static --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:x64-mingw-static --recurse +@if errorlevel 1 goto error +:skipgcc64 +@where /Q i686-w64-mingw32-g++.exe +@if errorlevel 1 goto skipgcc32 +.\vcpkg install directxtex:x86-mingw-static +@if errorlevel 1 goto :error +.\vcpkg install directxtex[dx12]:x86-mingw-static --recurse +@if errorlevel 1 goto :error +.\vcpkg install directxtex[tools]:x86-mingw-static --recurse +@if errorlevel 1 goto :error +.\vcpkg install directxtex:x86-mingw-dynamic +@if errorlevel 1 goto :error +.\vcpkg install directxtex[dx12]:x86-mingw-dynamic --recurse +@if errorlevel 1 goto :error +.\vcpkg install directxtex[tools]:x86-mingw-dynamic --recurse +@if errorlevel 1 goto :error +:skipgcc32 +@if "%GXDKLatest%."=="." goto finish +:xbox +.\vcpkg install directxtex:x64-xbox-scarlett +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-xbox-scarlett-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-xbox-xboxone +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-xbox-xboxone-static +@if errorlevel 1 goto error +@if exist "%VCPKG_ROOT%\installed\x64-windows\include\DirectXTex.h" .\vcpkg remove directxtex:x64-windows +@if errorlevel 1 goto error +.\vcpkg install directxtex[xbox,tools]:x64-windows --recurse +@if errorlevel 1 goto error +@goto finish +:clang +.\vcpkg install directxtex[core]:x64-clangcl-dynamic +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:x64-clangcl-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex[dx12]:x64-clangcl-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-clangcl-dynamic +@if errorlevel 1 goto error +.\vcpkg install directxtex[tools]:arm64-clangcl-dynamic --recurse +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-clangcl-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-uwp +@if errorlevel 1 goto error +.\vcpkg install directxtex:arm64-clangcl-uwp +@if errorlevel 1 goto error +@if "%GXDKLatest%."=="." goto finish +.\vcpkg install directxtex:x64-clangcl-scarlett +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-scarlett-static +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-xboxone +@if errorlevel 1 goto error +.\vcpkg install directxtex:x64-clangcl-xboxone-static +@if errorlevel 1 goto error +@if exist "%VCPKG_ROOT%\installed\x64-clangcl-dynamic\include\DirectXTex.h" .\vcpkg remove directxtex:x64-clangcl-dynamic +@if errorlevel 1 goto error +.\vcpkg install directxtex[xbox,tools]:x64-clangcl-dynamic --recurse +@if errorlevel 1 goto error +:finish +@echo SUCCEEDED +@if %1.==xbox. goto eof +@if %1.==clang. goto eof +@echo . +@echo . Run on x64-linux and arm64-linux +@echo . ./vcpkg install directxtex +@echo . ./vcpkg install directxtex[dx12] --recurse +@echo . ./vcpkg install directxtex[openexr] --recurse +@echo . ./vcpkg install directxtex[jpeg] --recurse +@echo . ./vcpkg install directxtex[png] --recurse +@where /Q x86_64-w64-mingw32-g++.exe +@if NOT errorlevel 1 goto gcc64 +@echo . +@echo . Run for MinGW64 +@echo . .\vcpkg install directxtex:x64-mingw-dynamic +@echo . .\vcpkg install directxtex[dx12]:x64-mingw-dynamic --recurse +@echo . .\vcpkg install directxtex[tools]:x64-mingw-dynamic --recurse +@echo . .\vcpkg install directxtex:x64-mingw-static +@echo . .\vcpkg install directxtex[dx12]:x64-mingw-static --recurse +@echo . .\vcpkg install directxtex[tools]:x64-mingw-static --recurse +:gcc64 +@where /Q i686-w64-mingw32-g++.exe +@if NOT errorlevel 1 goto gcc32 +@echo . +@echo . Run for MinGW32 +@echo . .\vcpkg install directxtex:x86-mingw-dynamic +@echo . .\vcpkg install directxtex[dx12]:x86-mingw-dynamic --recurse +@echo . .\vcpkg install directxtex[tools]:x86-mingw-dynamic --recurse +@echo . .\vcpkg install directxtex:x86-mingw-static +@echo . .\vcpkg install directxtex[dx12]:x86-mingw-static --recurse +@echo . .\vcpkg install directxtex[tools]:x86-mingw-static --recurse +:gcc32 +@goto eof +:error +@echo FAILED +:eof diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index df5fbd49..71a82c0d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -61,7 +61,7 @@ jobs: - uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.29.5 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: languages: c-cpp build-mode: manual @@ -75,6 +75,6 @@ jobs: run: cmake --build out\build\x64-Debug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.29.5 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: category: "/language:c-cpp" diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index 5ba752af..d74c765d 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -85,6 +85,6 @@ jobs: # Upload SARIF file to GitHub Code Scanning Alerts - name: Upload SARIF to GitHub - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.29.5 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: sarif_file: ${{ steps.run-analysis.outputs.sarif }} diff --git a/.gitignore b/.gitignore index d54f83a4..d374c3ae 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ x64 /CMakeUserPresets.json /build/vcpkg_installed /build/*.exe +!**/skills/** diff --git a/README.md b/README.md index 86d3185a..b88eed65 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,26 @@ These components are designed to work without requiring any content from the leg * Contains miscellaneous build files and scripts. +* ``skills\`` + + * Contains published CoPilot skills for use by developers. + ## Documentation Documentation is available on the [GitHub wiki](https://github.com/Microsoft/DirectXTex/wiki). +## CoPilot Usage + +For CoPilot CLI assistance with using DirectXTex, try: + +```bash +winget install GitHub.Copilot +winget install GitHub.cli +gh skill install microsoft/directxtex +copilot +/skills list +``` + ## Notices All content and source code for this package are subject to the terms of the [MIT License](https://github.com/microsoft/DirectXTex/blob/main/LICENSE). diff --git a/skills/directxtex-usage/SKILL.md b/skills/directxtex-usage/SKILL.md new file mode 100644 index 00000000..c6e89958 --- /dev/null +++ b/skills/directxtex-usage/SKILL.md @@ -0,0 +1,343 @@ +--- +name: directxtex-usage +description: >- + Guide for integrating and using the DirectXTex texture processing library in new projects. + Use this skill when asked about adding DirectXTex to a project, loading/saving textures, format conversion, + mipmap generation, block compression, or Direct3D resource creation. +license: MIT +metadata: + author: chuckw + version: "1.0" +--- + +# DirectXTex Usage Guide + +This skill provides guidance for integrating the DirectXTex texture processing library into a C++ project. + +## When to Use + +Invoke this skill when: + +- Adding DirectXTex as a dependency to a new or existing project. +- Writing code that processes texture data (resizing, format conversion, mipmap generation, DirectX Block Compression, etc.). +- Needing to understand the typical DirectXTex processing pipeline. + +## Overview + +DirectXTex is a texture processing library for Direct3D 11 and Direct3D 12 applications. It provides support for reading and writing DDS files, and performing various texture content processing operations including resizing, format conversion, mipmap generation, block compression, and normal map creation. + +- **Repository**: +- **Documentation**: +- **NuGet Packages**: `directxtex_desktop_win10`, `directxtex_uwp` +- **vcpkg Port**: `directxtex` + +## Integration Methods + +### vcpkg manifest-mode (Recommended) + +In your `vcpkg.json` file, add the following: + +```json +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "dependencies": [ + "directxtex" + ] +} +``` + +### vcpkg (classic) + +```bash +vcpkg install directxtex +``` + +Features: `dx12` (DirectX 12 API support), `openexr` (OpenEXR support), `tools` (command-line tools). Triplets: `x64-windows`, `x64-linux`, `arm64-windows`, etc. + +For DLL usage (`x64-windows` default triplet), define `DIRECTX_TEX_IMPORT` in your consuming project. For static library usage, use `-static-md` triplet variants. + +CMakeLists.txt: + +```cmake +find_package(directxtex CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE Microsoft::DirectXTex) +``` + +### NuGet + +Use `directxtex_desktop_win10` for Win32 desktop applications or `directxtex_uwp` for UWP apps. + +### Project Reference + +Add the appropriate `.vcxproj` from the `DirectXTex/` folder to your solution and add a project reference. Add the `DirectXTex` directory to your Additional Include Directories. + +## Header Include + +```cpp +#include // or — include BEFORE DirectXTex.h +#include + +using namespace DirectX; +``` + +For auxiliary features, include additional headers: + +```cpp +#include // OpenEXR support +#include // libjpeg support (non-WIC) +#include // libpng support (non-WIC) +#include // Xbox tiling extensions +``` + +> DirectXTexJPEG, DirectXTexPNG are typically only used on Linux. + +## Key Concepts + +### ScratchImage + +`ScratchImage` is the primary image container. It owns pixel memory and provides access to individual mip levels, array slices, and volume depth slices. + +```cpp +ScratchImage image; +HRESULT hr = LoadFromDDSFile(L"texture.dds", DDS_FLAGS_NONE, nullptr, image); +if (FAILED(hr)) + // handle error + +const TexMetadata& metadata = image.GetMetadata(); +const Image* img = image.GetImage(0, 0, 0); // mip 0, item 0, slice 0 +``` + +### TexMetadata + +Describes the texture dimensions, format, mip levels, array size, and type (1D, 2D, 3D, cubemap). + +### Blob + +A memory buffer used for serialized output (e.g., saving to memory rather than files). + +### Error Handling + +All processing functions return `HRESULT`. Check with `FAILED()` / `SUCCEEDED()` macros. + +## Common Workflows + +### Loading Textures + +```cpp +// From DDS file +ScratchImage image; +HRESULT hr = LoadFromDDSFile(L"texture.dds", DDS_FLAGS_NONE, nullptr, image); + +// From WIC file (PNG, BMP, JPEG, TIFF, etc.) — Windows only +ScratchImage image; +HRESULT hr = LoadFromWICFile(L"texture.png", WIC_FLAGS_NONE, nullptr, image); + +// From TGA file +ScratchImage image; +HRESULT hr = LoadFromTGAFile(L"texture.tga", TGA_FLAGS_NONE, nullptr, image); + +// From HDR file +ScratchImage image; +HRESULT hr = LoadFromHDRFile(L"texture.hdr", nullptr, image); + +// From memory +ScratchImage image; +HRESULT hr = LoadFromDDSMemory(pData, dataSize, DDS_FLAGS_NONE, nullptr, image); +``` + +### Saving Textures + +```cpp +// Save to DDS file +const Image* img = image.GetImages(); +size_t nimages = image.GetImageCount(); +const TexMetadata& metadata = image.GetMetadata(); +HRESULT hr = SaveToDDSFile(img, nimages, metadata, DDS_FLAGS_NONE, L"output.dds"); + +// Save single image to WIC file (PNG) — Windows only +hr = SaveToWICFile(*image.GetImage(0, 0, 0), WIC_FLAGS_NONE, + GetWICCodec(WIC_CODEC_PNG), L"output.png"); + +// Save to memory blob +Blob blob; +hr = SaveToDDSMemory(img, nimages, metadata, DDS_FLAGS_NONE, blob); +``` + +### Format Conversion + +```cpp +ScratchImage converted; +HRESULT hr = Convert(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + DXGI_FORMAT_R8G8B8A8_UNORM, TEX_FILTER_DEFAULT, TEX_THRESHOLD_DEFAULT, converted); +``` + +### Resizing + +```cpp +ScratchImage resized; +HRESULT hr = Resize(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + 1024, 1024, TEX_FILTER_DEFAULT, resized); +``` + +### Mipmap Generation + +```cpp +ScratchImage mipChain; +HRESULT hr = GenerateMipMaps(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + TEX_FILTER_DEFAULT, 0, mipChain); +// 0 levels = generate full mip chain +``` + +### Block Compression + +```cpp +ScratchImage compressed; +HRESULT hr = Compress(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + DXGI_FORMAT_BC7_UNORM, TEX_COMPRESS_DEFAULT, TEX_THRESHOLD_DEFAULT, compressed); + +// GPU-accelerated BC6H/BC7 compression (Direct3D 11) +ScratchImage compressed; +HRESULT hr = Compress(pDevice, image.GetImages(), image.GetImageCount(), image.GetMetadata(), + DXGI_FORMAT_BC7_UNORM, TEX_COMPRESS_DEFAULT, TEX_ALPHA_WEIGHT_DEFAULT, compressed); +``` + +### Decompression + +```cpp +ScratchImage decompressed; +HRESULT hr = Decompress(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + DXGI_FORMAT_R8G8B8A8_UNORM, decompressed); +``` + +### Normal Map Generation + +```cpp +ScratchImage normalMap; +HRESULT hr = ComputeNormalMap(*image.GetImage(0, 0, 0), + CNMAP_CHANNEL_LUMINANCE, 2.0f, + DXGI_FORMAT_R8G8B8A8_UNORM, normalMap); +``` + +### Premultiplied Alpha + +```cpp +ScratchImage pmAlpha; +HRESULT hr = PremultiplyAlpha(image.GetImages(), image.GetImageCount(), image.GetMetadata(), + TEX_PMALPHA_DEFAULT, pmAlpha); +``` + +### Creating Direct3D 11 Resources + +```cpp +#include +#include + +// Create texture resource +ID3D11Resource* pTexture = nullptr; +HRESULT hr = CreateTexture(pDevice, image.GetImages(), image.GetImageCount(), + image.GetMetadata(), &pTexture); + +// Create shader resource view directly +ID3D11ShaderResourceView* pSRV = nullptr; +hr = CreateShaderResourceView(pDevice, image.GetImages(), image.GetImageCount(), + image.GetMetadata(), &pSRV); +``` + +### Creating Direct3D 12 Resources + +```cpp +#include +#include + +// Create committed resource +ID3D12Resource* pTexture = nullptr; +HRESULT hr = CreateTexture(pDevice, image.GetMetadata(), &pTexture); + +// Prepare upload data for CopyTextureRegion +std::vector subresources; +hr = PrepareUpload(pDevice, image.GetImages(), image.GetImageCount(), + image.GetMetadata(), subresources); +``` + +## Typical Texture Pipeline + +A common offline texture processing pipeline: + +```cpp +// 1. Load source image +ScratchImage source; +HRESULT hr = LoadFromWICFile(L"diffuse.png", WIC_FLAGS_NONE, nullptr, source); +if (FAILED(hr)) return hr; + +// 2. Resize if needed +ScratchImage resized; +if (source.GetMetadata().width != 1024 || source.GetMetadata().height != 1024) +{ + hr = Resize(*source.GetImage(0, 0, 0), 1024, 1024, TEX_FILTER_DEFAULT, resized); + if (FAILED(hr)) return hr; +} +else +{ + resized = std::move(source); +} + +// 3. Generate mipmaps +ScratchImage mipChain; +hr = GenerateMipMaps(*resized.GetImage(0, 0, 0), TEX_FILTER_DEFAULT, 0, mipChain); +if (FAILED(hr)) return hr; + +// 4. Compress to BC7 +ScratchImage compressed; +hr = Compress(mipChain.GetImages(), mipChain.GetImageCount(), mipChain.GetMetadata(), + DXGI_FORMAT_BC7_UNORM, TEX_COMPRESS_DEFAULT, TEX_THRESHOLD_DEFAULT, compressed); +if (FAILED(hr)) return hr; + +// 5. Save as DDS +hr = SaveToDDSFile(compressed.GetImages(), compressed.GetImageCount(), + compressed.GetMetadata(), DDS_FLAGS_NONE, L"diffuse.dds"); +``` + +## Format Utilities + +DirectXTex provides utility functions for querying DXGI format properties: + +```cpp +bool compressed = IsCompressed(DXGI_FORMAT_BC7_UNORM); // true +size_t bpp = BitsPerPixel(DXGI_FORMAT_R8G8B8A8_UNORM); // 32 +bool srgb = IsSRGB(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); // true + +DXGI_FORMAT srgbFmt = MakeSRGB(DXGI_FORMAT_R8G8B8A8_UNORM); // _SRGB variant +DXGI_FORMAT linearFmt = MakeLinear(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); // non-SRGB + +size_t rowPitch, slicePitch; +ComputePitch(DXGI_FORMAT_R8G8B8A8_UNORM, 256, 256, rowPitch, slicePitch); +``` + +## Platform Support + +| Platform | DDS | HDR | TGA | WIC | Direct3D 11 | Direct3D 12 | +| --- | --- | --- | --- | --- | --- | --- | +| Windows desktop | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| UWP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Xbox (GDK) | ✓ | ✓ | ✓ | — | ✓ | ✓ | +| Linux | ✓ | ✓ | ✓ | — | — | — | + +## Command-Line Tools + +DirectXTex includes three CLI tools for texture processing: + +- **texconv** — Convert images to DDS with compression, mipmaps, and resizing +- **texassemble** — Create cubemaps, texture arrays, and volume maps from individual images +- **texdiag** — Inspect and validate DDS files + +Example texconv usage: + +```bash +texconv -f BC7_UNORM -m 0 -y diffuse.png +``` + +## Further Reading + +- [Getting Started](https://github.com/microsoft/DirectXTex/wiki/Getting-Started) +- [DirectXTex Wiki](https://github.com/microsoft/DirectXTex/wiki) +- [API Reference](reference/overview.md) diff --git a/skills/directxtex-usage/reference/overview.md b/skills/directxtex-usage/reference/overview.md new file mode 100644 index 00000000..735e0046 --- /dev/null +++ b/skills/directxtex-usage/reference/overview.md @@ -0,0 +1,304 @@ +# DirectXTex API Reference + +This document provides an overview of the DirectXTex public API. Full function signatures with SAL annotations can be found in `DirectXTex/DirectXTex.h`. + +## Namespace + +All DirectXTex functions and types reside in the `DirectX` namespace. + +## DXGI Format Utilities + +| Function | Description | +| --- | --- | +| `IsValid` | Returns true if fmt is a valid DXGI_FORMAT value | +| `IsCompressed` | Returns true for BC1–BC7 block-compressed formats | +| `IsPacked` | Returns true for packed formats (e.g., R8G8_B8G8) | +| `IsVideo` | Returns true for video-specific formats | +| `IsPlanar` | Returns true for planar formats (e.g., NV12) | +| `IsPalettized` | Returns true for palettized formats | +| `IsDepthStencil` | Returns true for depth/stencil formats | +| `IsSRGB` | Returns true for sRGB formats | +| `IsBGR` | Returns true for BGR-ordered formats | +| `IsTypeless` | Returns true for typeless formats | +| `HasAlpha` | Returns true if the format includes an alpha channel | +| `BitsPerPixel` | Returns bits per pixel for the format | +| `BitsPerColor` | Returns bits per color channel | +| `BytesPerBlock` | Returns bytes per block for compressed formats | +| `FormatDataType` | Returns the data type classification (float, unorm, etc.) | +| `ComputePitch` | Computes row and slice pitch for a given format and dimensions | +| `ComputeScanlines` | Computes number of scanlines including BC padding | +| `CalculateMipLevels` | Calculates valid mip level count for 1D/2D textures | +| `CalculateMipLevels3D` | Calculates valid mip level count for volume textures | +| `MakeSRGB` | Converts format to its sRGB equivalent | +| `MakeLinear` | Converts format to its linear (non-sRGB) equivalent | +| `MakeTypeless` | Converts format to its typeless equivalent | +| `MakeTypelessUNORM` | Converts typeless format to UNORM equivalent | +| `MakeTypelessFLOAT` | Converts typeless format to FLOAT equivalent | + +## Structures + +### TexMetadata + +Describes complete texture resource properties. + +| Field | Type | Description | +| --- | --- | --- | +| `width` | `size_t` | Texture width in pixels | +| `height` | `size_t` | Texture height (1 for 1D textures) | +| `depth` | `size_t` | Texture depth (1 for 1D/2D textures) | +| `arraySize` | `size_t` | Array size (multiple of 6 for cubemaps) | +| `mipLevels` | `size_t` | Number of mip levels | +| `miscFlags` | `uint32_t` | Miscellaneous flags (e.g., `TEX_MISC_TEXTURECUBE`) | +| `miscFlags2` | `uint32_t` | Additional flags (alpha mode encoded here) | +| `format` | `DXGI_FORMAT` | Pixel format | +| `dimension` | `TEX_DIMENSION` | Resource dimension (1D, 2D, 3D) | + +Methods: `ComputeIndex`, `IsCubemap`, `IsPMAlpha`, `SetAlphaMode`, `GetAlphaMode`, `IsVolumemap`, `CalculateSubresource` + +### DDSMetaData + +Contains the original DDS pixel format header information for advanced use cases. + +### Image + +Describes a single 2D image surface within a `ScratchImage`. + +| Field | Type | Description | +| --- | --- | --- | +| `width` | `size_t` | Image width | +| `height` | `size_t` | Image height | +| `format` | `DXGI_FORMAT` | Pixel format | +| `rowPitch` | `size_t` | Bytes per row | +| `slicePitch` | `size_t` | Total bytes for the image | +| `pixels` | `uint8_t*` | Pointer to pixel data | + +### ScratchImage + +RAII container that owns texture pixel data. Move-only (copy deleted). + +| Method | Description | +| --- | --- | +| `Initialize` | Initialize from TexMetadata | +| `Initialize1D` / `Initialize2D` / `Initialize3D` | Initialize for specific dimension | +| `InitializeCube` | Initialize as cubemap | +| `InitializeFromImage` | Initialize from a single Image | +| `InitializeArrayFromImages` | Initialize array from multiple Images | +| `InitializeCubeFromImages` | Initialize cubemap from face Images | +| `Initialize3DFromImages` | Initialize volume from depth-slice Images | +| `Release` | Free all memory | +| `OverrideFormat` | Change format tag without conversion | +| `GetMetadata` | Access TexMetadata | +| `GetImage` | Access specific image in the texture | +| `GetImages` / `GetImageCount` | Access all images | +| `GetPixels` / `GetPixelsSize` | Access raw pixel memory | +| `IsAlphaAllOpaque` | Check if alpha is all opaque | + +### Blob + +16-byte-aligned memory buffer for serialized output. + +| Method | Description | +| --- | --- | +| `Initialize` | Allocate buffer | +| `Release` | Free buffer | +| `GetBufferPointer` | Get mutable pointer | +| `GetConstBufferPointer` | Get const pointer | +| `GetBufferSize` | Get buffer size | +| `Resize` | Reallocate to new size | +| `Trim` | Reduce size without reallocation | + +### Rect + +Simple rectangle for `CopyRectangle` operations: `x`, `y`, `w`, `h`. + +### TileShape + +Describes a tile shape for tiled/reserved resources (D3D11/D3D12 interop). + +## Image I/O Functions + +> See `DirectXTex/DirectXTex.h` for full function signatures with SAL annotations. + +### DDS + +| Function | Description | +| --- | --- | +| `GetMetadataFromDDSFile` | Read metadata from a DDS file | +| `GetMetadataFromDDSMemory` | Read metadata from DDS data in memory | +| `GetMetadataFromDDSFileEx` | Read metadata and pixel format from a DDS file | +| `GetMetadataFromDDSMemoryEx` | Read metadata and pixel format from DDS data in memory | +| `LoadFromDDSFile` | Load a DDS file into a ScratchImage | +| `LoadFromDDSMemory` | Load DDS data from memory into a ScratchImage | +| `LoadFromDDSFileEx` | Load a DDS file with extended pixel format info | +| `LoadFromDDSMemoryEx` | Load DDS data from memory with extended pixel format info | +| `SaveToDDSFile` | Save image(s) to a DDS file | +| `SaveToDDSMemory` | Save image(s) to a DDS blob in memory | + +### HDR (Radiance RGBE) + +| Function | Description | +| --- | --- | +| `GetMetadataFromHDRFile` | Read metadata from an HDR file | +| `GetMetadataFromHDRMemory` | Read metadata from HDR data in memory | +| `LoadFromHDRFile` | Load an HDR file into a ScratchImage | +| `LoadFromHDRMemory` | Load HDR data from memory into a ScratchImage | +| `SaveToHDRFile` | Save a single image to an HDR file | +| `SaveToHDRMemory` | Save a single image to an HDR blob in memory | + +### TGA (Targa) + +| Function | Description | +| --- | --- | +| `GetMetadataFromTGAFile` | Read metadata from a TGA file | +| `GetMetadataFromTGAMemory` | Read metadata from TGA data in memory | +| `LoadFromTGAFile` | Load a TGA file into a ScratchImage | +| `LoadFromTGAMemory` | Load TGA data from memory into a ScratchImage | +| `SaveToTGAFile` | Save a single image to a TGA file | +| `SaveToTGAMemory` | Save a single image to a TGA blob in memory | + +### WIC (Windows only — PNG, BMP, JPEG, TIFF, GIF, etc.) + +| Function | Description | +| --- | --- | +| `GetMetadataFromWICFile` | Read metadata from a WIC-supported file | +| `GetMetadataFromWICMemory` | Read metadata from WIC-supported data in memory | +| `LoadFromWICFile` | Load a WIC-supported file into a ScratchImage | +| `LoadFromWICMemory` | Load WIC-supported data from memory into a ScratchImage | +| `SaveToWICFile` | Save image(s) to a WIC-supported file format | +| `SaveToWICMemory` | Save image(s) to a WIC-supported blob in memory | + +## Texture Processing Functions + +### Resize + +| Function | Description | +| --- | --- | +| `Resize` | Resize image(s) to a new width and height | + +### Convert (Format Conversion) + +| Function | Description | +| --- | --- | +| `Convert` | Convert image(s) to a new pixel format | +| `ConvertEx` | Convert with extended options and progress callback | +| `ConvertToSinglePlane` | Convert planar format to equivalent non-planar format | + +### Mipmap Generation + +| Function | Description | +| --- | --- | +| `GenerateMipMaps` | Generate a full or partial mipmap chain for 1D/2D textures | +| `GenerateMipMaps3D` | Generate a mipmap chain for volume (3D) textures | +| `ScaleMipMapsAlphaForCoverage` | Adjust mip alpha values to preserve coverage | + +### Block Compression + +| Function | Description | +| --- | --- | +| `Compress` | CPU block compression (BC1–BC7) | +| `Compress` (D3D11) | GPU-accelerated BC6H/BC7 compression via DirectCompute | +| `CompressEx` | Compress with extended options and progress callback | +| `CompressEx` (D3D11) | GPU-accelerated compress with extended options | +| `Decompress` | Decompress block-compressed image(s) to a standard format | + +### Flip/Rotate (Windows only) + +| Function | Description | +| --- | --- | +| `FlipRotate` | Flip and/or rotate image(s) | + +### Premultiplied Alpha + +| Function | Description | +| --- | --- | +| `PremultiplyAlpha` | Convert between straight and premultiplied alpha | + +### Normal Map + +| Function | Description | +| --- | --- | +| `ComputeNormalMap` | Generate a normal map from a height map image | + +### Misc Image Operations + +| Function | Description | +| --- | --- | +| `CopyRectangle` | Copy a rectangular region between images | +| `ComputeMSE` | Compute mean-squared error between two images | +| `EvaluateImage` | Iterate over image pixels with a read-only callback | +| `TransformImage` | Transform image pixels with a read/write callback | + +## DDS Helper Functions + +| Function | Description | +| --- | --- | +| `EncodeDDSHeader` | Encode a DDS header from TexMetadata | + +## Tiling Utilities + +| Function | Description | +| --- | --- | +| `ComputeTileShape` | Compute the tile dimensions for a given format and dimension | + +## WIC Utilities (Windows only) + +| Function | Description | +| --- | --- | +| `GetWICCodec` | Get the WIC container format GUID for a codec enum | +| `GetWICFactory` | Get the shared WIC imaging factory | +| `SetWICFactory` | Set a custom WIC imaging factory | + +## Direct3D 11 Interop + +| Function | Description | +| --- | --- | +| `IsSupportedTexture` | Check if a texture format/layout is supported by the device | +| `CreateTexture` | Create a D3D11 texture resource from image data | +| `CreateShaderResourceView` | Create a D3D11 SRV from image data | +| `CreateTextureEx` | Create a D3D11 texture with explicit usage/bind flags | +| `CreateShaderResourceViewEx` | Create a D3D11 SRV with explicit usage/bind flags | +| `CaptureTexture` | Copy a D3D11 texture resource into a ScratchImage | + +## Direct3D 12 Interop + +| Function | Description | +| --- | --- | +| `IsSupportedTexture` | Check if a texture format/layout is supported by the device | +| `CreateTexture` | Create a D3D12 committed resource from metadata | +| `CreateTextureEx` | Create a D3D12 committed resource with explicit resource flags | +| `PrepareUpload` | Prepare subresource data for upload via copy queue | +| `CaptureTexture` | Copy a D3D12 texture resource into a ScratchImage | + +## Flags Enumerations + +| Enum | Purpose | +| --- | --- | +| `CP_FLAGS` | Pitch computation alignment options | +| `DDS_FLAGS` | DDS load/save behavior options | +| `TGA_FLAGS` | TGA load/save options | +| `WIC_FLAGS` | WIC load/save options | +| `TEX_FR_FLAGS` | Flip/rotate operations | +| `TEX_FILTER_FLAGS` | Filtering mode for resize/convert/mipgen | +| `TEX_PMALPHA_FLAGS` | Premultiplied alpha conversion options | +| `TEX_COMPRESS_FLAGS` | Block compression options | +| `CNMAP_FLAGS` | Normal map generation options | +| `CMSE_FLAGS` | Mean-squared error comparison options | +| `CREATETEX_FLAGS` | Direct3D texture creation options | + +## Auxiliary Modules + +### DirectXTexEXR (`Auxiliary/DirectXTexEXR.h`) + +OpenEXR format support via the OpenEXR library. + +### DirectXTexJPEG (`Auxiliary/DirectXTexJPEG.h`) + +JPEG support via libjpeg (cross-platform, does not require WIC). + +### DirectXTexPNG (`Auxiliary/DirectXTexPNG.h`) + +PNG support via libpng (cross-platform, does not require WIC). + +### DirectXTexXbox (`Auxiliary/DirectXTexXbox.h`) + +Xbox-specific tiling/detiling and DDS extensions for Xbox One and Xbox Series X|S. diff --git a/skills/texture-assembler/SKILL.md b/skills/texture-assembler/SKILL.md new file mode 100644 index 00000000..8e65ac8e --- /dev/null +++ b/skills/texture-assembler/SKILL.md @@ -0,0 +1,176 @@ +--- +name: texture-assembler +description: >- + Guide for using the texassemble command-line tool to create cubemaps, volume maps, texture arrays, and other assembled DDS textures from individual images. + Use this skill when asked about creating cubemaps, volume textures, texture arrays, merging channels, converting animated GIFs to textures, or extracting + cubemap faces to cross/strip layouts. +license: MIT +metadata: + author: chuckw + version: "1.0" +--- + +# Texassemble Texture Assembler + +This skill provides guidance for using the **texassemble** command-line tool to create DDS files containing cubemaps, volume maps, or texture arrays from individual images. + +## When to Use + +Invoke this skill when: + +- Creating cubemaps from six individual face images. +- Creating volume (3D) textures from multiple slice images. +- Creating 1D or 2D texture arrays from multiple images. +- Creating cubemap arrays from multiple sets of face images. +- Extracting cubemap faces into cross, strip, or tee layout images. +- Creating cubemaps from cross, strip, or tee layout images. +- Merging channels from two images into one output. +- Converting animated GIFs into texture arrays. +- Creating textures with custom mipmap levels from individual mip images. + +## Installation + +### winget (Recommended) + +```bash +winget install Microsoft.DirectXTex.Texassemble +``` + +### vcpkg + +```bash +vcpkg install directxtex[tools] +``` + +## Syntax + +```plaintext +texassemble [options] [--file-list ] +``` + +Input files can be `dds`, `tga`, `hdr`, or any WIC-supported format (`bmp`, `jpg`, `png`, `jxr`, `heif`, `webp`, etc.). + +The command-line uses Windows-style `-` or `/` for options. It also supports `--version`, `--help`, and GNU long-option style parameters with `--`. + +## Commands + +| Command | Description | +| --- | --- | +| `cube` | Creates a cubemap from six face images (ordered: +X, -X, +Y, -Y, +Z, -Z) | +| `volume` | Creates a volume (3D) texture from two or more images (depth = image count) | +| `array` | Creates a 1D or 2D texture array from two or more images (requires FL 10.0+) | +| `cubearray` | Creates a cubemap array from a multiple of six images (requires FL 10.1+) | +| `h-cross` | Extracts cubemap faces into a horizontal cross layout image | +| `v-cross` | Extracts cubemap faces into a vertical cross layout image | +| `v-cross-fnz` | Same as `v-cross` but flips the negative-Z face | +| `h-strip` | Extracts cubemap faces into a horizontal strip image | +| `v-strip` | Extracts cubemap faces into a vertical strip image | +| `h-tee` | Extracts cubemap faces into a horizontal "T" layout image | +| `cube-from-hc` | Creates a cubemap from a horizontal cross layout image | +| `cube-from-vc` | Creates a cubemap from a vertical cross layout image | +| `cube-from-vc-fnz` | Creates a cubemap from a vertical cross layout (flipped -Z) image | +| `cube-from-ht` | Creates a cubemap from a horizontal tee layout image | +| `cube-from-hs` | Creates a cubemap from a horizontal strip image | +| `cube-from-vs` | Creates a cubemap from a vertical strip image | +| `array-strip` | Extracts a 1D/2D array into a horizontal strip image | +| `merge` | Creates a texture by merging channels from two input images | +| `gif` | Converts an animated GIF into a texture array | +| `from-mips` | Creates a 2D mipmapped texture from individual mip images | +| `cube-from-mips` | Creates a cubemap texture from individual mip images | + +## Common Workflows + +### Create a cubemap from six face images + +```plaintext +texassemble cube -w 256 -h 256 -o cubemap.dds posx.jpg negx.jpg posy.jpg negy.jpg posz.jpg negz.jpg +``` + +### Create a volume (3D) texture + +```plaintext +texassemble volume -w 256 -h 256 -o volume.dds slice0.png slice1.png slice2.png slice3.png +``` + +### Create a texture array + +```plaintext +texassemble array -o array.dds frame0.png frame1.png frame2.png frame3.png +``` + +### Extract cubemap to horizontal cross layout + +```plaintext +texassemble h-cross cubemap.dds +``` + +### Create cubemap from a vertical cross image + +```plaintext +texassemble cube-from-vc -o cubemap.dds cross_layout.png +``` + +### Merge channels from two images + +```plaintext +texassemble merge -o combined.png color.png alpha_source.bmp +``` + +### Merge with custom swizzle (roughness into alpha) + +```plaintext +texassemble merge --swizzle rgbR -o packed.png albedo.png roughness.png +``` + +### Convert animated GIF to texture array + +```plaintext +texassemble gif -o animation.dds animated.gif +``` + +### Create mipmapped texture from individual mip images + +```plaintext +texassemble from-mips -o texture.dds mip0.png mip1.png mip2.png mip3.png +``` + +## Options Reference + +See [reference/options.md](reference/options.md) for the complete options reference. + +### Quick Reference (most common options) + +| Option | Description | +| --- | --- | +| `-o ` | Output filename (default: DDS based on first input, BMP for cross/strip) | +| `-f ` | Output DXGI format (e.g., `R8G8B8A8_UNORM`, `B8G8R8A8_UNORM`) | +| `-w ` / `-h ` | Output width / height in pixels | +| `-if ` | Image filter (`POINT`, `LINEAR`, `CUBIC`, `FANT`, `BOX`, `TRIANGLE`) | +| `-srgb` | Input and output are sRGB | +| `-y` | Overwrite existing output file | +| `-dx10` | Force DX10 header extension | +| `-fl ` | Target feature level (default: `11.0`, max texture size: 16384) | +| `--swizzle ` | Channel swizzle for `merge` command | +| `--strip-mips` | Strip mipmaps from input textures | +| `-r` | Recursive wildcard search | +| `-nologo` | Suppress copyright message | + +## Output Format + +By default, texassemble writes DDS files. The output filename is derived from the first input file with a `.dds` extension. For cross/strip extraction commands, the default output is a `.bmp` file and you can specify any supported image extension. + +## Notes + +- The tool does **not** support mipmap generation or texture compression. Use the **texture-converter** skill to further process the resulting DDS file. +- Any texture-compressed input file is decompressed on load. +- Partial cubemaps are not supported; all six faces must be provided. +- Cubemap face order is: positive-X, negative-X, positive-Y, negative-Y, positive-Z, negative-Z. +- Support for OpenEXR (`exr`) format requires building from source with `USE_OPENEXR` defined. +- Additional WIC codecs (HEIF, WEBP) work automatically if installed on the system. +- Texture arrays require Direct3D feature level 10.0 or better hardware. +- Cubemap arrays with more than one cubemap require feature level 10.1 or better. + +## Further Reading + +- [Texassemble Wiki](https://github.com/microsoft/DirectXTex/wiki/Texassemble) +- [DirectXTex Documentation](https://github.com/microsoft/DirectXTex/wiki) diff --git a/skills/texture-assembler/reference/examples.md b/skills/texture-assembler/reference/examples.md new file mode 100644 index 00000000..0f13ec34 --- /dev/null +++ b/skills/texture-assembler/reference/examples.md @@ -0,0 +1,298 @@ +# Texassemble Usage Examples + +This document provides practical examples for common texture assembly scenarios. + +## Cubemaps + +### Create a cubemap from six JPEG face images + +```plaintext +texassemble cube -w 256 -h 256 -o cubemap.dds posx.jpg negx.jpg posy.jpg negy.jpg posz.jpg negz.jpg +``` + +Faces must be ordered: positive-X, negative-X, positive-Y, negative-Y, positive-Z, negative-Z. + +### Create a cubemap with explicit format + +```plaintext +texassemble cube -w 512 -h 512 -f R16G16B16A16_FLOAT -o hdr_cubemap.dds posx.hdr negx.hdr posy.hdr negy.hdr posz.hdr negz.hdr +``` + +### Create a cubemap from a horizontal cross layout + +```plaintext +texassemble cube-from-hc -o cubemap.dds cross_layout.png +``` + +### Create a cubemap from a vertical cross layout + +```plaintext +texassemble cube-from-vc -o cubemap.dds vertical_cross.png +``` + +### Create a cubemap from a vertical cross (flipped -Z) + +```plaintext +texassemble cube-from-vc-fnz -o cubemap.dds vertical_cross_fnz.png +``` + +### Create a cubemap from a horizontal strip + +```plaintext +texassemble cube-from-hs -o cubemap.dds strip.png +``` + +### Create a cubemap from a vertical strip + +```plaintext +texassemble cube-from-vs -o cubemap.dds strip.png +``` + +### Create a cubemap from a horizontal tee layout + +```plaintext +texassemble cube-from-ht -o cubemap.dds tee_layout.png +``` + +## Cubemap Extraction + +### Extract cubemap faces to horizontal cross + +```plaintext +texassemble h-cross cubemap.dds +``` + +Output defaults to `cubemap.bmp`. Specify a different format with `-o`: + +```plaintext +texassemble h-cross -o cubemap_cross.png cubemap.dds +``` + +### Extract to vertical cross + +```plaintext +texassemble v-cross -o cubemap_vcross.png cubemap.dds +``` + +### Extract to vertical cross with flipped -Z face + +```plaintext +texassemble v-cross-fnz -o cubemap_vcross.png cubemap.dds +``` + +### Extract to horizontal strip + +```plaintext +texassemble h-strip -o cubemap_strip.png cubemap.dds +``` + +### Extract to vertical strip + +```plaintext +texassemble v-strip -o cubemap_vstrip.png cubemap.dds +``` + +### Extract to horizontal tee + +```plaintext +texassemble h-tee -o cubemap_tee.png cubemap.dds +``` + +## Volume (3D) Textures + +### Create a volume texture from image slices + +```plaintext +texassemble volume -w 256 -h 256 -o volume.dds slice0.png slice1.png slice2.png slice3.png +``` + +The number of input images determines the depth of the volume texture. + +### Create a volume texture with sRGB colorspace + +```plaintext +texassemble volume -w 128 -h 128 -srgb -o volume_srgb.dds slice*.png +``` + +### Create a volume texture from mixed formats + +```plaintext +texassemble volume -w 256 -h 256 -f R8G8B8A8_UNORM -o volume.dds lena.jpg fishingboat.jpg peppers.tiff +``` + +## Texture Arrays + +### Create a 2D texture array + +```plaintext +texassemble array -o array.dds frame0.png frame1.png frame2.png frame3.png +``` + +The size is taken from the first input image; subsequent images are resized to match. + +### Create a texture array with explicit size + +```plaintext +texassemble array -w 512 -h 512 -o array.dds *.png +``` + +### Create a texture array with file list + +```plaintext +texassemble array -o array.dds --file-list textures.txt +``` + +### Extract array to horizontal strip + +```plaintext +texassemble array-strip -o strip.png array.dds +``` + +## Cubemap Arrays + +### Create a cubemap array (two cubemaps = 12 images) + +```plaintext +texassemble cubearray -w 256 -h 256 -o cubearray.dds env0_px.jpg env0_nx.jpg env0_py.jpg env0_ny.jpg env0_pz.jpg env0_nz.jpg env1_px.jpg env1_nx.jpg env1_py.jpg env1_ny.jpg env1_pz.jpg env1_nz.jpg +``` + +Input must be a multiple of six images. Each group of six forms one cubemap. + +## Merging Channels + +### Merge RGB from one image with alpha from another (default behavior) + +```plaintext +texassemble merge -o combined.png albedo.png alpha_mask.bmp +``` + +Default swizzle is `rgbB`: RGB from first image, blue channel of second as alpha. + +### Merge with alpha channel from second image + +```plaintext +texassemble merge --swizzle rgbA -o combined.png color.png mask.png +``` + +### Pack roughness into alpha channel + +```plaintext +texassemble merge --swizzle rgbR -o packed.dds albedo.png roughness.png +``` + +### Create ORM map (Occlusion, Roughness, Metallic) + +```plaintext +texassemble merge --swizzle Rgb -o orm_partial.png occlusion.png roughness.png +``` + +Then merge metallic into the blue channel with a second pass: + +```plaintext +texassemble merge --swizzle rgB -o orm.png orm_partial.png metallic.png +``` + +### Use all channels from second image + +```plaintext +texassemble merge --swizzle RGBA -o output.dds unused.png source.png +``` + +### Zero out alpha, keep RGB + +```plaintext +texassemble merge --swizzle rgb0 -o no_alpha.png color.png unused.png +``` + +## Animated GIFs + +### Convert animated GIF to DDS texture array + +```plaintext +texassemble gif -o animation.dds animated.gif +``` + +Output format is `DXGI_FORMAT_B8G8R8A8_UNORM` with one array item per frame. + +### Convert GIF using file background color + +```plaintext +texassemble gif --gif-bg-color -o animation.dds animated.gif +``` + +## Custom Mipmaps + +### Create a 2D texture with custom mip levels + +```plaintext +texassemble from-mips -o texture.dds mip0_256x256.png mip1_128x128.png mip2_64x64.png mip3_32x32.png +``` + +Images are ordered from largest (mip 0) to smallest. + +### Create a cubemap with custom mip levels + +```plaintext +texassemble cube-from-mips -o cubemap.dds mip0_face0.png mip0_face1.png ... mip1_face0.png ... +``` + +## Pipeline Examples + +### Create cubemap then compress with texconv + +```plaintext +texassemble cube -w 512 -h 512 -o cubemap_raw.dds posx.hdr negx.hdr posy.hdr negy.hdr posz.hdr negz.hdr +texconv -f BC6H_UF16 -m 0 -y cubemap_raw.dds +``` + +### Create texture array then add mipmaps and compression + +```plaintext +texassemble array -w 1024 -h 1024 -o sprites_raw.dds sprite*.png +texconv -f BC7_UNORM_SRGB -srgb -m 0 -y sprites_raw.dds +``` + +### Create volume texture then compress + +```plaintext +texassemble volume -w 64 -h 64 -o noise3d_raw.dds noise*.png +texconv -f BC4_UNORM -m 0 -y noise3d_raw.dds +``` + +## Miscellaneous + +### Use recursive wildcard for inputs + +```plaintext +texassemble array -r -w 256 -h 256 -o array.dds C:\Textures\*.png +``` + +### Suppress copyright message + +```plaintext +texassemble cube -nologo -o cubemap.dds face*.png +``` + +### Force DX10 header extension + +```plaintext +texassemble array -dx10 -o array.dds *.png +``` + +### Strip mipmaps from mip-mapped input textures + +```plaintext +texassemble array --strip-mips -o array.dds mipped_tex1.dds mipped_tex2.dds +``` + +### Overwrite existing output + +```plaintext +texassemble cube -y -o cubemap.dds face*.jpg +``` + +### Apply tonemap when assembling HDR sources + +```plaintext +texassemble cube --tonemap -w 256 -h 256 -o cubemap_ldr.dds posx.hdr negx.hdr posy.hdr negy.hdr posz.hdr negz.hdr +``` diff --git a/skills/texture-assembler/reference/options.md b/skills/texture-assembler/reference/options.md new file mode 100644 index 00000000..728e043c --- /dev/null +++ b/skills/texture-assembler/reference/options.md @@ -0,0 +1,128 @@ +# Texassemble Options Reference + +Complete reference for all texassemble command-line options. Options use Windows-style `-` or `/` prefixes. GNU long-form options use `--`. + +## File Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-r` | | Recursive wildcard search for input files | +| `-flist ` | `--file-list ` | Read input filenames from a text file (one per line). Lines starting with `#` are comments | +| `-o ` | | Output filename. Default: DDS based on first input (BMP for cross/strip commands) | +| `-l` | `--to-lowercase` | Force output path and filename to lowercase | +| `-y` | `--overwrite` | Overwrite existing output file. By default, the tool aborts if the output exists | + +## Pixel Format Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-f ` | `--format ` | Output DXGI format (without `DXGI_FORMAT_` prefix). If omitted, uses format of first input | + +## Resizing Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-w ` | `--width ` | Output width in pixels | +| `-h ` | `--height ` | Output height in pixels. If no size given, uses size of first input | + +## Filtering Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-if ` | `--image-filter ` | Image filter for resizing (see below) | +| `-wrap` | | Wrap texture addressing mode for filtering | +| `-mirror` | | Mirror texture addressing mode for filtering | +| `-nowic` | | Force non-WIC filtering code paths | + +### Filter Values + +| Filter | Description | +| --- | --- | +| `POINT` | Nearest-neighbor (no interpolation) | +| `LINEAR` | Bilinear interpolation | +| `CUBIC` | Bicubic interpolation | +| `FANT` | Fant (equivalent to box for downscaling) | +| `BOX` | Box filter | +| `TRIANGLE` | Triangle (tent) filter | + +Each filter also has `_DITHER` (4×4 ordered dither) and `_DITHER_DIFFUSION` (error diffusion dither) variants: +- `POINT_DITHER`, `POINT_DITHER_DIFFUSION` +- `LINEAR_DITHER`, `LINEAR_DITHER_DIFFUSION` +- `CUBIC_DITHER`, `CUBIC_DITHER_DIFFUSION` +- `FANT_DITHER`, `FANT_DITHER_DIFFUSION` +- `BOX_DITHER`, `BOX_DITHER_DIFFUSION` +- `TRIANGLE_DITHER`, `TRIANGLE_DITHER_DIFFUSION` + +## Colorspace Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-srgb` | | Both input and output are sRGB (gamma ~2.2) | +| `-srgbi` | `--srgb-in` | Only input is sRGB | +| `-srgbo` | `--srgb-out` | Only output is sRGB | +| | `--tonemap` | Apply Reinhard tonemap operator (HDR→LDR based on max luminosity) | + +## Alpha Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-alpha` | | Convert premultiplied alpha to straight (non-premultiplied) alpha | +| `-sepalpha` | `--separate-alpha` | Separate alpha channel for resize | + +## DirectDraw Surface (DDS) File Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-dx10` | | Force DX10 header extension. Enables alpha mode metadata. May not be compatible with legacy D3DX10/D3DX11 | + +## Direct3D Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-fl ` | `--feature-level ` | Target feature level constraining maximum texture size | + +### Feature Levels + +| Level | Max Texture Size | +| --- | --- | +| `9.1`, `9.2` | 2048 | +| `9.3` | 4096 | +| `10.0`, `10.1` | 8192 | +| `11.0`, `11.1`, `12.0`, `12.1` | 16384 (default) | + +## GIF Options + +| Option | Long Form | Description | +| --- | --- | --- | +| | `--gif-bg-color` | Use the background color metadata from the GIF file instead of transparent background (default is transparent, matching browser behavior) | + +## Merge Options + +| Option | Long Form | Description | +| --- | --- | --- | +| | `--swizzle ` | Channel swizzle mask for the `merge` command (default: `rgbB`) | + +### Swizzle Mask Format + +The swizzle mask is 1–4 characters using HLSL-style channel notation: + +- **Lowercase** letters pull from the **first** image: `r`, `g`, `b`, `a`, `x`, `y`, `z`, `w` +- **Uppercase** letters pull from the **second** image: `R`, `G`, `B`, `A`, `X`, `Y`, `Z`, `W` +- `0` sets the channel to zero +- `1` sets the channel to maximum + +Examples: +- `rgbB` — RGB from first image, blue of second image as alpha (default) +- `rgbA` — RGB from first image, alpha of second image as alpha +- `RGBA` — All channels from the second image +- `rgbG` — RGB from first image, green of second image as alpha +- `rg01` — Red and green from first image, blue=0, alpha=max + +## Miscellaneous Options + +| Option | Long Form | Description | +| --- | --- | --- | +| | `--strip-mips` | For `cube`, `array`, `volume`, or `cubearray` commands: strips mipchain from mip-mapped input textures | +| `-nologo` | | Suppress copyright message | +| | `--version` | Display version information | +| | `--help` | Display usage help | diff --git a/skills/texture-converter/SKILL.md b/skills/texture-converter/SKILL.md new file mode 100644 index 00000000..1094f792 --- /dev/null +++ b/skills/texture-converter/SKILL.md @@ -0,0 +1,161 @@ +--- +name: texture-converter +description: >- + Guide for using the texconv command-line texture conversion tool. Use this skill when asked about converting textures, compressing images + to DDS/BC formats, generating mipmaps, resizing textures, creating normal maps, or performing HDR tone mapping from the command line. +license: MIT +metadata: + author: chuckw + version: "1.0" +--- + +# Texconv Texture Converter + +This skill provides guidance for using the **texconv** command-line tool to convert, compress, resize, and process texture images. + +## When to Use + +Invoke this skill when: + +- Converting image files (PNG, BMP, JPG, TGA, HDR, etc.) to DDS or other formats. +- Applying block compression (BC1–BC7) to textures for runtime use. +- Generating mipmaps for texture files. +- Resizing textures or fitting them to power-of-2 dimensions. +- Creating normal maps from height maps. +- Performing HDR tone mapping or colorspace conversions. +- Batch-processing texture files using wildcards or file lists. + +## Installation + +### winget (Recommended) + +```bash +winget install Microsoft.DirectXTex.Texconv +``` + +### vcpkg + +```bash +vcpkg install directxtex[tools] +``` + +## Syntax + +```plaintext +texconv [options] [--file-list ] +``` + +Input files can be `dds`, `tga`, `hdr`, `phm`, `ppm`, `pfm`, or any WIC-supported format (`bmp`, `jpg`, `png`, `jxr`, `heif`, `webp`, etc.). + +The command-line uses Windows-style `-` or `/` for options. It also supports `--version`, `--help`, and GNU long-option style parameters with `--`. + +## Common Workflows + +### Convert to BC7 compressed DDS with mipmaps + +```plaintext +texconv -f BC7_UNORM -m 0 -y diffuse.png +``` + +### Convert to BC1 (DXT1) with power-of-2 resize + +```plaintext +texconv -pow2 -f BC1_UNORM cat.jpg +``` + +### Batch convert all PNG files recursively + +```plaintext +texconv -r C:\Textures\*.png +``` + +### Convert HDR to BMP with tone mapping + +```plaintext +texconv myimage.hdr -tonemap -ft BMP +``` + +### Generate normal map from height map + +```plaintext +texconv -nmap lo -nmapamp 2 -f R8G8B8A8_UNORM heightmap.png +``` + +### Convert for legacy Direct3D 9 with feature level cap + +```plaintext +texconv -pow2 -fl 9.3 -f BC3_UNORM -m 1 *.bmp +``` + +### Output to a specific directory with prefix/suffix + +```plaintext +texconv -o output_dir -px hd_ -sx _bc7 -f BC7_UNORM *.png +``` + +### Convert to PNG from DDS + +```plaintext +texconv -ft png -y texture.dds +``` + +### Premultiplied alpha conversion + +```plaintext +texconv -pmalpha -f BC3_UNORM ui_element.png +``` + +### HDR10 colorspace conversion + +```plaintext +texconv --rotate-color 709toHDR10 -nits 200 -f R10G10B10A2_UNORM scene.hdr +``` + +### Swizzle channels + +```plaintext +texconv --swizzle rrrg -f BC5_UNORM normal.png +``` + +## Options Reference + +See [reference/options.md](reference/options.md) for the complete options reference. + +### Quick Reference (most common options) + +| Option | Description | +| --- | --- | +| `-f ` | Output DXGI format (e.g., `BC7_UNORM`, `R8G8B8A8_UNORM`) | +| `-ft ` | Output file type (`dds`, `png`, `bmp`, `jpg`, `tga`, `hdr`, etc.) | +| `-o ` | Output directory | +| `-y` | Overwrite existing files | +| `-m ` | Mipmap levels (`0` = full chain, `1` = none) | +| `-w ` / `-h ` | Output width / height in pixels | +| `-pow2` | Fit to power-of-2 dimensions | +| `-if ` | Image filter (`POINT`, `LINEAR`, `CUBIC`, `FANT`, `BOX`, `TRIANGLE`) | +| `-srgb` | Input and output are sRGB | +| `-pmalpha` | Convert to premultiplied alpha | +| `-bc ` | BC compression flags (`u`, `d`, `q`, `x`) | +| `-nmap ` | Generate normal map from height map | +| `-r` | Recursive wildcard search | +| `-nologo` | Suppress copyright message | + +## Output Format + +By default, texconv writes DDS files. The output filename matches the input filename with the appropriate extension. Use `-ft` to change the output format, `-o` for output directory, and `-px`/`-sx` for filename prefix/suffix. + +## Notes + +- When no size is specified (`-w` / `-h`), the output size matches the input. +- DDS output defaults to generating all mipmap levels (`-m 0`). Use `-m 1` to suppress mipmaps. +- BC6H and BC7 compression uses GPU acceleration by default when available. Use `-nogpu` to force CPU. +- For cubemaps, volume maps, or texture arrays from individual files, use **texassemble** instead. +- Support for OpenEXR (`exr`) format requires building from source with `USE_OPENEXR` defined. +- Additional WIC codecs (HEIF, WEBP) work automatically if installed on the system. + +## Further Reading + +- [Texconv Wiki](https://github.com/microsoft/DirectXTex/wiki/Texconv) +- [DirectXTex Documentation](https://github.com/microsoft/DirectXTex/wiki) +- [Image Formats](https://github.com/microsoft/DirectXTex/wiki/Image-formats) +- [Filter Flags](https://github.com/microsoft/DirectXTex/wiki/Filter-Flags) diff --git a/skills/texture-converter/reference/examples.md b/skills/texture-converter/reference/examples.md new file mode 100644 index 00000000..980d708b --- /dev/null +++ b/skills/texture-converter/reference/examples.md @@ -0,0 +1,413 @@ +# Texconv Usage Examples + +This document provides practical examples for common texture conversion scenarios. + +## Basic Conversions + +### Convert PNG to DDS with default settings (mipmaps, no compression) + +```plaintext +texconv -y texture.png +``` + +### Convert with BC7 compression (highest quality) + +```plaintext +texconv -f BC7_UNORM -y diffuse.png +``` + +### Convert with sRGB-aware BC7 compression + +```plaintext +texconv -f BC7_UNORM_SRGB -srgb -y diffuse.png +``` + +### Convert DDS back to PNG + +```plaintext +texconv -ft png -y texture.dds +``` + +### Convert to JPEG with quality setting + +```plaintext +texconv -ft jpg -wicq 0.9 -y screenshot.bmp +``` + +## Batch Processing + +### Convert all PNG files in current directory + +```plaintext +texconv -f BC7_UNORM -y *.png +``` + +### Recursively convert all textures preserving directory structure + +```plaintext +texconv -r:keep -f BC7_UNORM -o output -y C:\Assets\*.png +``` + +### Convert files from a list + +```plaintext +texconv -f BC7_UNORM -y --file-list textures.txt +``` + +### Convert with filename modifications + +```plaintext +texconv -f BC7_UNORM -px compiled_ -sx _bc7 -o build\textures -y *.png +``` + +## Resizing + +### Resize to specific dimensions + +```plaintext +texconv -w 1024 -h 1024 -f BC7_UNORM -y large_texture.png +``` + +### Fit to power-of-2 (preserving aspect ratio) + +```plaintext +texconv -pow2 -f BC1_UNORM -y photo.jpg +``` + +### Fit to power-of-2 with feature level cap (max 4096) + +```plaintext +texconv -pow2 -fl 9.3 -f BC3_UNORM -y photo.jpg +``` + +## Mipmap Control + +### Generate full mipmap chain (default for DDS) + +```plaintext +texconv -m 0 -f BC7_UNORM -y texture.png +``` + +### No mipmaps (single level) + +```plaintext +texconv -m 1 -f BC7_UNORM -y ui_element.png +``` + +### Specific number of mip levels + +```plaintext +texconv -m 5 -f BC7_UNORM -y texture.png +``` + +### Preserve alpha coverage in mipmaps (for foliage/hair) + +```plaintext +texconv -f BC7_UNORM --keep-coverage 0.5 -y foliage.png +``` + +## Normal Maps + +### Generate normal map from height map (using luminance) + +```plaintext +texconv -nmap lo -nmapamp 2.0 -f R8G8B8A8_UNORM -y heightmap.png +``` + +### Generate normal map using red channel with higher amplitude + +```plaintext +texconv -nmap ro -nmapamp 4.0 -f BC5_UNORM -y heightmap.png +``` + +### Convert OpenGL normal map to Direct3D convention + +```plaintext +texconv --invert-y -f BC5_UNORM -y normal_opengl.png +``` + +### Reconstruct Z channel from XY-only normal map (BC5) + +```plaintext +texconv --reconstruct-z -ft png -y normal_bc5.dds +``` + +### Swizzle for two-channel normal maps + +```plaintext +texconv --swizzle rg -f BC5_UNORM -y normal_map.png +``` + +## Alpha Handling + +### Convert to premultiplied alpha + +```plaintext +texconv -pmalpha -f BC3_UNORM -y ui_panel.png +``` + +### Convert premultiplied alpha back to straight alpha + +```plaintext +texconv -alpha -ft png -y premultiplied.dds +``` + +### Separate alpha processing (non-transparency alpha data) + +```plaintext +texconv -sepalpha -f BC3_UNORM -y packed_texture.png +``` + +### Apply chromakey (green screen removal) + +```plaintext +texconv -c 00FF00 -f BC7_UNORM -y greenscreen.png +``` + +### Set alpha threshold for BC1 1-bit alpha + +```plaintext +texconv -at 0.3 -f BC1_UNORM -y cutout.png +``` + +## HDR and Colorspace + +### Tone map HDR to LDR + +```plaintext +texconv --tonemap -ft bmp -y environment.hdr +``` + +### Convert to HDR10 signal + +```plaintext +texconv --rotate-color 709toHDR10 --paper-white-nits 200 -f R10G10B10A2_UNORM -y scene.exr +``` + +### Convert HDR10 back to linear Rec.709 + +```plaintext +texconv --rotate-color HDR10to709 -f R16G16B16A16_FLOAT -y hdr10_signal.dds +``` + +### Convert Rec.709 to Display P3 + +```plaintext +texconv --rotate-color 709toDisplayP3 -f R10G10B10A2_UNORM -y wide_gamut.png +``` + +### Force sRGB interpretation on output only + +```plaintext +texconv -srgbo -f R8G8B8A8_UNORM_SRGB -y linear_source.hdr +``` + +### Ignore embedded sRGB metadata + +```plaintext +texconv --ignore-srgb -f BC7_UNORM -y image_with_bad_metadata.png +``` + +## Block Compression Options + +### BC7 with maximum quality (slow) + +```plaintext +texconv -f BC7_UNORM -bc x -y texture.png +``` + +### BC7 with quick/minimal compression (fast) + +```plaintext +texconv -f BC7_UNORM -bc q -y texture.png +``` + +### BC1-BC3 with dithering + +```plaintext +texconv -f BC1_UNORM -bc d -y texture.png +``` + +### BC1-BC3 with uniform weighting (instead of perceptual) + +```plaintext +texconv -f BC1_UNORM -bc u -y texture.png +``` + +### Force GPU compression for BC6H/BC7 + +```plaintext +texconv -f BC7_UNORM -gpu 0 -y texture.png +``` + +### Force CPU-only compression + +```plaintext +texconv -f BC7_UNORM -nogpu -y texture.png +``` + +### Adjust alpha weight for BC7 + +```plaintext +texconv -f BC7_UNORM -aw 2.0 -y texture_with_important_alpha.png +``` + +## Image Operations + +### Flip vertically (common for OpenGL↔DirectX) + +```plaintext +texconv -vflip -f BC7_UNORM -y texture.png +``` + +### Flip horizontally + +```plaintext +texconv -hflip -ft png -y mirrored.png +``` + +### Swizzle: extract alpha to grayscale + +```plaintext +texconv --swizzle aaaa -ft png -y texture_with_alpha.dds +``` + +### Swizzle: move red channel to alpha, zero RGB + +```plaintext +texconv --swizzle 000r -f BC4_UNORM -y roughness.png +``` + +### Swizzle: pack channels + +```plaintext +texconv --swizzle rg01 -f R8G8_UNORM -y normal_xy.png +``` + +## DDS-Specific Options + +### Force DX10 header (required for some formats) + +```plaintext +texconv -f BC7_UNORM -dx10 -y texture.png +``` + +### Force legacy DX9 header + +```plaintext +texconv -f BC1_UNORM -dx9 -y texture.png +``` + +### Handle typeless format as UNORM + +```plaintext +texconv -tu -ft png -y typeless_texture.dds +``` + +### Fix non-multiple-of-4 BC texture + +```plaintext +texconv --fix-bc-4x4 -f BC7_UNORM -y odd_size.dds +``` + +### Load permissive/malformed DDS + +```plaintext +texconv --permissive -ft png -y legacy_texture.dds +``` + +### Expand luminance formats to RGBA + +```plaintext +texconv -xlum -ft png -y lightmap.dds +``` + +## TGA Options + +### Write TGA 2.0 with metadata + +```plaintext +texconv -ft tga -tga20 -y texture.png +``` + +### Preserve zero alpha in TGA + +```plaintext +texconv --tga-zero-alpha -f R8G8B8A8_UNORM -y legacy.tga +``` + +## Filtering Options + +### Use point filtering (no interpolation) + +```plaintext +texconv -w 512 -h 512 -if POINT -y pixel_art.png +``` + +### Use cubic filtering with dithering + +```plaintext +texconv -w 256 -h 256 -if CUBIC_DITHER -f BC1_UNORM -y photo.png +``` + +### Wrap addressing for tileable textures + +```plaintext +texconv -wrap -f BC7_UNORM -y tileable.png +``` + +### Mirror addressing + +```plaintext +texconv -mirror -f BC7_UNORM -y symmetric.png +``` + +## Game Asset Pipeline Examples + +### Diffuse texture (sRGB, BC7, full mipmaps) + +```plaintext +texconv -f BC7_UNORM_SRGB -srgb -m 0 -y diffuse.png +``` + +### Normal map (BC5, linear, full mipmaps) + +```plaintext +texconv -f BC5_UNORM -m 0 -y normal.png +``` + +### Roughness/metallic packed map + +```plaintext +texconv -f BC7_UNORM -m 0 -y orm.png +``` + +### Environment cubemap face (HDR, BC6H) + +```plaintext +texconv -f BC6H_UF16 -m 0 -y env_posx.hdr +``` + +### UI texture (no mipmaps, high quality) + +```plaintext +texconv -f BC7_UNORM_SRGB -srgb -m 1 -y button.png +``` + +### Sprite atlas (premultiplied alpha, no mipmaps) + +```plaintext +texconv -pmalpha -f BC3_UNORM_SRGB -srgb -m 1 -y sprites.png +``` + +### Foliage with alpha coverage preservation + +```plaintext +texconv -f BC7_UNORM_SRGB -srgb --keep-coverage 0.5 -y leaves.png +``` + +### Legacy Direct3D 9 target + +```plaintext +texconv -pow2 -fl 9.3 -f BC1_UNORM -dx9 -m 0 -y legacy_texture.bmp +``` diff --git a/skills/texture-converter/reference/formats.md b/skills/texture-converter/reference/formats.md new file mode 100644 index 00000000..4c34563b --- /dev/null +++ b/skills/texture-converter/reference/formats.md @@ -0,0 +1,112 @@ +# Texconv Supported Formats + +This document lists the DXGI formats supported by texconv for the `-f` / `--format` option. + +## Format Aliases + +These short-form aliases are accepted in addition to the full DXGI format names: + +| Alias | DXGI Format | +| --- | --- | +| `DXT1` | `DXGI_FORMAT_BC1_UNORM` | +| `DXT2`, `DXT3` | `DXGI_FORMAT_BC2_UNORM` | +| `DXT4`, `DXT5` | `DXGI_FORMAT_BC3_UNORM` | +| `BGRA` | `DXGI_FORMAT_B8G8R8A8_UNORM` | +| `BGR` | `DXGI_FORMAT_B8G8R8X8_UNORM` | +| `FP16` | `DXGI_FORMAT_R16G16B16A16_FLOAT` | +| `FP32` | `DXGI_FORMAT_R32G32B32A32_FLOAT` | +| `RGBA` | `DXGI_FORMAT_R8G8B8A8_UNORM` | +| `BC3n`, `DXT5nm` | BC3 variant for normal maps (swapped channels) | +| `RXGB` | Custom FourCC DXT5 variant for normal maps (use with `-dx9`) | + +## Block Compression Formats + +| Format | Description | Use Case | +| --- | --- | --- | +| `BC1_UNORM` | 4:1 compression, 1-bit alpha | Opaque or cutout textures | +| `BC1_UNORM_SRGB` | BC1 with sRGB | Opaque diffuse/albedo | +| `BC2_UNORM` | 4:1 compression, explicit 4-bit alpha | Sharp alpha transitions | +| `BC2_UNORM_SRGB` | BC2 with sRGB | Rarely used | +| `BC3_UNORM` | 4:1 compression, interpolated alpha | Smooth alpha gradients | +| `BC3_UNORM_SRGB` | BC3 with sRGB | Diffuse with smooth alpha | +| `BC4_UNORM` | Single-channel (red) | Height maps, roughness | +| `BC4_SNORM` | Single-channel signed | Signed single-channel data | +| `BC5_UNORM` | Two-channel (red + green) | Normal maps (XY) | +| `BC5_SNORM` | Two-channel signed | Signed normal maps | +| `BC6H_UF16` | HDR unsigned half-float | HDR environment maps | +| `BC6H_SF16` | HDR signed half-float | HDR with negative values | +| `BC7_UNORM` | High-quality RGBA | High-quality textures | +| `BC7_UNORM_SRGB` | BC7 with sRGB | High-quality diffuse/albedo | + +## Common Uncompressed Formats + +| Format | Description | +| --- | --- | +| `R8G8B8A8_UNORM` | 32-bit RGBA | +| `R8G8B8A8_UNORM_SRGB` | 32-bit RGBA sRGB | +| `B8G8R8A8_UNORM` | 32-bit BGRA | +| `B8G8R8X8_UNORM` | 32-bit BGR (no alpha) | +| `R16G16B16A16_FLOAT` | 64-bit RGBA half-float | +| `R32G32B32A32_FLOAT` | 128-bit RGBA float | +| `R10G10B10A2_UNORM` | 10:10:10:2 HDR display | +| `R16G16_UNORM` | Two-channel 16-bit | +| `R8G8_UNORM` | Two-channel 8-bit | +| `R8_UNORM` | Single-channel 8-bit | +| `A8_UNORM` | Alpha-only 8-bit | +| `R16_FLOAT` | Single-channel half-float | +| `R32_FLOAT` | Single-channel float | +| `R9G9B9E5_SHAREDEXP` | Shared-exponent HDR | +| `R11G11B10_FLOAT` | Packed HDR (no alpha) | + +## Output File Types + +Specified with `-ft` / `--file-type`: + +| Type | Extensions | Notes | +| --- | --- | --- | +| `dds` | `.dds`, `.ddx` | Default. Supports mipmaps, arrays, cubemaps, BC | +| `bmp` | `.bmp` | Windows bitmap | +| `jpg` / `jpeg` | `.jpg` | Lossy compression. Quality via `-wicq` | +| `png` | `.png` | Lossless with alpha | +| `tga` | `.tga` | Truevision. Use `-tga20` for 2.0 extension | +| `hdr` | `.hdr` | Radiance RGBE for HDR images | +| `tif` / `tiff` | `.tif` | Multi-page, various compressions | +| `jxr` / `wdp` / `hdp` | `.jxr` | JPEG XR / HD Photo | +| `ppm` / `pfm` | `.ppm`, `.pfm` | Portable pixmap/floatmap (Netpbm) | +| `exr` | `.exr` | OpenEXR (requires `USE_OPENEXR` build) | + +## Format Selection Guidelines + +### Diffuse/Albedo Textures +- **BC7_UNORM_SRGB**: Best quality, slower compression +- **BC1_UNORM_SRGB**: Good quality for opaque, 4× smaller than BC7 +- **BC3_UNORM_SRGB**: When smooth alpha is needed + +### Normal Maps +- **BC5_UNORM**: Two-channel XY (reconstruct Z in shader) +- **BC7_UNORM**: When 3-channel normals are needed +- Use `--reconstruct-z` when converting from BC5 back to RGBA + +### HDR / Environment Maps +- **BC6H_UF16**: Compressed HDR +- **R16G16B16A16_FLOAT**: Uncompressed HDR +- **R9G9B9E5_SHAREDEXP**: Compact HDR (read-only in some hardware) + +### Single-Channel (Roughness, Height, AO) +- **BC4_UNORM**: Compressed single-channel +- **R8_UNORM**: Uncompressed single-channel + +### UI / Text +- **BC7_UNORM**: High-quality with alpha +- **R8G8B8A8_UNORM**: When artifacts are unacceptable + +## Feature Level Texture Size Limits + +| Feature Level | Max Texture 2D Size | Max Volume Depth | +| --- | --- | --- | +| 9.1 | 2048 | 256 | +| 9.2 | 2048 | 256 | +| 9.3 | 4096 | 256 | +| 10.0 | 8192 | 2048 | +| 10.1 | 8192 | 2048 | +| 11.0–12.2 | 16384 | 2048 | diff --git a/skills/texture-converter/reference/options.md b/skills/texture-converter/reference/options.md new file mode 100644 index 00000000..9a41cbcc --- /dev/null +++ b/skills/texture-converter/reference/options.md @@ -0,0 +1,237 @@ +# Texconv Options Reference + +Complete reference for all texconv command-line options. Options use Windows-style `-` or `/` prefixes. GNU long-form options use `--` and accept space, `=`, or `:` as value separators (e.g., `--width 100`, `--width=100`, `--width:100`). + +## File Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-r` | | Recursive wildcard search. Use `-r:keep` to preserve subdirectory structure, `-r:flatten` (default) to flatten | +| `-flist ` | `--file-list ` | Read input filenames from a text file (one per line). Lines starting with `#` are comments | +| `-o ` | | Output directory | +| `-px ` | `--prefix ` | Prefix for output filename | +| `-sx ` | `--suffix ` | Suffix for output filename | +| `-l` | `--to-lowercase` | Force output path and filename to lowercase | +| `-y` | `--overwrite` | Overwrite existing output files. By default, existing files are skipped | + +## File and Pixel Format Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-ft ` | `--file-type ` | Output file type (default: `dds`) | +| `-f ` | `--format ` | Output DXGI format (without `DXGI_FORMAT_` prefix) | + +### Supported Output File Types + +| Type | Extensions | Notes | +| --- | --- | --- | +| `bmp` | `.bmp` | Windows BMP | +| `jpg`, `jpeg` | `.jpg` | JPEG (lossy, use `-wicq` for quality) | +| `png` | `.png` | PNG (lossless with alpha) | +| `dds`, `ddx` | `.dds` | DirectDraw Surface (default) | +| `tga` | `.tga` | Truevision TGA | +| `hdr` | `.hdr` | Radiance RGBE | +| `tif`, `tiff` | `.tif` | Tagged Image File Format | +| `wdp`, `hdp`, `jxr` | `.jxr` | JPEG XR / Windows Media Photo | +| `ppm`, `pfm` | `.ppm`, `.pfm` | Portable PixMap / FloatMap (Netpbm) | +| `exr` | `.exr` | OpenEXR (requires `USE_OPENEXR` build) | + +### Common Format Aliases + +| Alias | DXGI Format | +| --- | --- | +| `DXT1` | `BC1_UNORM` | +| `DXT2`, `DXT3` | `BC2_UNORM` | +| `DXT4`, `DXT5` | `BC3_UNORM` | +| `BGRA` | `B8G8R8A8_UNORM` | +| `BGR` | `B8G8R8X8_UNORM` | +| `FP16` | `R16G16B16A16_FLOAT` | +| `FP32` | `R32G32B32A32_FLOAT` | +| `RGBA` | `R8G8B8A8_UNORM` | + +## Resize and Mipmap Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-w ` | `--width ` | Output width in pixels | +| `-h ` | `--height ` | Output height in pixels | +| `-m ` | `--mip-levels ` | Mipmap levels to generate. `0` = full chain (default for DDS), `1` = no mipmaps | +| `-pow2` | `--fit-power-of-2` | Fit to power-of-2 dimensions, minimizing aspect ratio changes. Max size governed by `-fl` | + +## Filtering Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-if ` | `--image-filter ` | Image filter for resizing (see below) | +| `-wrap` | | Wrap texture addressing mode for filtering | +| `-mirror` | | Mirror texture addressing mode for filtering | +| `-nowic` | | Force non-WIC filtering code paths | + +### Filter Values + +| Filter | Description | +| --- | --- | +| `POINT` | Nearest-neighbor (no interpolation) | +| `LINEAR` | Bilinear interpolation | +| `CUBIC` | Bicubic interpolation | +| `FANT` | Fant (equivalent to box for downscaling) | +| `BOX` | Box filter | +| `TRIANGLE` | Triangle (tent) filter | + +Each filter also has `_DITHER` (4×4 ordered dither) and `_DITHER_DIFFUSION` (error diffusion dither) variants: +- `POINT_DITHER`, `POINT_DITHER_DIFFUSION` +- `LINEAR_DITHER`, `LINEAR_DITHER_DIFFUSION` +- `CUBIC_DITHER`, `CUBIC_DITHER_DIFFUSION` +- `FANT_DITHER`, `FANT_DITHER_DIFFUSION` +- `BOX_DITHER`, `BOX_DITHER_DIFFUSION` +- `TRIANGLE_DITHER`, `TRIANGLE_DITHER_DIFFUSION` + +## Colorspace Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-srgb` | | Both input and output are sRGB (gamma ~2.2) | +| `-srgbi` | `--srgb-in` | Only input is sRGB | +| `-srgbo` | `--srgb-out` | Only output is sRGB | +| | `--rotate-color ` | Color rotation / HDR10 curve conversion | +| `-nits ` | `--paper-white-nits ` | Paper-white nits for HDR10 conversions (default: 200.0, max: 10000) | +| | `--tonemap` | Apply Reinhard tonemap operator (HDR→LDR based on max luminosity) | +| | `--ignore-srgb` | Ignore colorspace metadata in source WIC/TGA files | + +### Color Rotation Values + +| Value | Description | +| --- | --- | +| `709to2020` | Rec.709 → Rec.2020 color primaries | +| `2020to709` | Rec.2020 → Rec.709 color primaries | +| `709toHDR10` | Rec.709 → Rec.2020 + ST.2084 curve (HDR10 signal) | +| `HDR10to709` | HDR10 signal → Rec.709 linear values | +| `P3to2020` | DCI-P3 → Rec.2020 color primaries | +| `P3toHDR10` | DCI-P3 → Rec.2020 + ST.2084 curve (HDR10 signal) | +| `709toDisplayP3` | Rec.709 → Display-P3 (D65 white point) | +| `DisplayP3to709` | Display-P3 (D65 white point) → Rec.709 | + +## Alpha Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-pmalpha` | `--premultiplied-alpha` | Convert to premultiplied alpha. Sets `DDS_ALPHA_MODE_PREMULTIPLIED` unless alpha is all opaque | +| `-alpha` | | Convert premultiplied alpha to straight (non-premultiplied) alpha | +| `-sepalpha` | `--separate-alpha` | Separate alpha channel for resize/mipmap generation. Implies `DDS_ALPHA_MODE_CUSTOM` | +| `-at ` | `--alpha-threshold ` | Alpha threshold for 1-bit alpha formats (BC1, RGBA5551). Default: 0.5 | +| | `--keep-coverage ` | Preserve alpha coverage in generated mipmaps for alpha test reference value (0 to 1) | +| `-c ` | `--color-key ` | Chromakey color in hexadecimal RGB. Replaces matching color with alpha 0.0. E.g., `00FF00` for green | + +## Block Compression (BC) Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-bc ` | `--block-compress ` | BC compression flags (combinable) | +| `-gpu ` | | Use GPU at adapter index for BC6H/BC7 (default: 0) | +| `-nogpu` | | Force software codec for BC6H/BC7 | +| | `--single-proc` | Disable OpenMP multi-threading for BC6H/BC7 | +| `-aw ` | `--alpha-weight ` | Alpha weight for BC7 GPU compressor error metric (default: 1.0) | + +### BC Compression Flags + +| Flag | Applies To | Description | +| --- | --- | --- | +| `u` | BC1–BC3 | Uniform weighting (instead of perceptual) | +| `d` | BC1–BC3 | Enable dithering | +| `q` | BC7 | Quick/minimal compression (mode 6 only) | +| `x` | BC7 | Maximum compression (enables modes 0 & 2) | + +## Normal Map Generation Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-nmap ` | `--normal-map ` | Convert height map to normal map (flags below) | +| `-nmapamp ` | `--normal-map-amplitude ` | Normal map amplitude (default: 1.0) | +| | `--invert-y` | Invert green channel (OpenGL↔Direct3D normal convention) | +| | `--reconstruct-z` | Rebuild Z (blue) channel assuming X/Y are normals (for BC5 → RGBA) | +| | `--x2-bias` | Enable `*2 - 1` conversion for unorm↔float/snorm (used with normal maps) | + +### Normal Map Flags + +Must include one channel source flag (`r`, `g`, `b`, `a`, or `l`): + +| Flag | Description | +| --- | --- | +| `r` | Use red channel as height | +| `g` | Use green channel as height | +| `b` | Use blue channel as height | +| `a` | Use alpha channel as height | +| `l` | Use luminance (from RGB) as height | + +Optional modifier flags: + +| Flag | Description | +| --- | --- | +| `m` | Mirror in U & V (default: wrap) | +| `u` | Mirror in U only | +| `v` | Mirror in V only | +| `i` | Invert sign of computed normal | +| `o` | Compute rough occlusion term in alpha channel | + +## Image Operation Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-hflip` | `--horizontal-flip` | Horizontal flip | +| `-vflip` | `--vertical-flip` | Vertical flip | +| | `--swizzle ` | Swizzle channels using HLSL-style mask (1–4 chars: `rgba`, `rrra`, `rg01`, etc.). `0` = zero, `1` = max | + +## DirectDraw Surface (DDS) File Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-tu` | `--typeless-unorm` | Treat typeless formats as UNORM | +| `-tf` | `--typeless-float` | Treat typeless formats as FLOAT | +| `-dword` | `--dword-alignment` | Use DWORD alignment for legacy 24bpp files | +| | `--bad-tails` | Tolerate incorrect DXTn mipchain blocks smaller than 4×4 | +| | `--permissive` | Allow malformed/variant DDS headers to load | +| | `--ignore-mips` | Load only top-level mipmap | +| | `--fix-bc-4x4` | Resize non-multiple-of-4 BC textures to valid dimensions | +| `-xlum` | `--expand-luminance` | Expand L8/A8L8/L16 to 8:8:8:8 or 16:16:16:16 (instead of 1 or 2 channel) | +| `-dx10` | | Force DX10 header extension (enables alpha mode metadata, may break legacy readers) | +| `-dx9` | | Force legacy DX9 headers (fails for BC6/BC7/UINT/SINT, strips SRGB) | + +## Targa TruVision (TGA) File Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-tga20` | | Include TGA 2.0 extension area (gamma, alpha mode, timestamp) | +| | `--tga-zero-alpha` | Preserve all-zero alpha channels as-is (default treats as opaque) | + +## Windows Image Component (WIC) Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-wicq ` | `--wic-quality ` | Image quality 0.0–1.0 (applies to `jpg`, `tif`, `heif`, `jxr`) | +| | `--wic-lossless` | Lossless encoding (applies to `jxr`). Ignores wic-quality | +| | `--wic-uncompressed` | Uncompressed encoding (applies to `tif`, `heif`). Ignores wic-quality | +| | `--wic-multiframe` | Write multiframe images (applies to `gif`, `tif`). Default writes first frame only | + +## Direct3D Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-fl ` | `--feature-level ` | Target feature level constraining max texture size | + +### Feature Levels + +| Level | Max 2D Texture Size | +| --- | --- | +| `9.1`, `9.2` | 2048 | +| `9.3` | 4096 | +| `10.0`, `10.1` | 8192 | +| `11.0`, `11.1`, `12.0`, `12.1`, `12.2` | 16384 (default) | + +## Miscellaneous Options + +| Option | Long Form | Description | +| --- | --- | --- | +| `-nologo` | | Suppress copyright message | +| | `--timing` | Display compression timing information | +| | `--version` | Display version information | +| | `--help` | Display usage help |