---
title: "Switch from the DXC command line"
url: https://recursiveai.org/oneshader/cookbook/migrate-from-dxc/
description: "Replace dxc -spirv with oneshader in a Makefile, CMake or script build: which DXC flags it takes unchanged, what it adds (MSL and WGSL targets, reflection…"
version: "1.2.0"
---

# Switch from the DXC command line

Replace `dxc -spirv` with `oneshader` in a Makefile, CMake or script build: which DXC flags it takes unchanged, what it adds (MSL and WGSL targets, reflection JSON, a dependency file), and which DXC options it rejects.

`oneshader`, from `RecursiveAI.OneShader.Tool`, takes DXC’s core flags, so a DXC command line that emits SPIR-V for a vertex, pixel or compute shader mostly works unchanged. It needs the .NET 10 runtime:

```sh
dotnet tool install -g RecursiveAI.OneShader.Tool --version 1.2.0
oneshader --version
```

## A Makefile, before and after

`shaders/post.hlsl` includes `shaders/common/color.hlsli` and uses a macro from the command line:

```hlsl
#include "color.hlsli"
Texture2D<float4> Scene : register(t0);
SamplerState Linear : register(s1);

float4 main(float2 uv : TEXCOORD0) : SV_Target
{
    return float4(Tonemap(Scene.Sample(Linear, uv).rgb * EXPOSURE), 1);
}
```

The only change to the Makefile is the compiler’s name, plus `--depfile`, so that editing the include rebuilds the shader:

```make
# Was: DXC = dxc
DXC = oneshader
FLAGS = -spirv -O3 -HV 2021 -WX -I shaders/common -D EXPOSURE=1.5

build/post.spv: shaders/post.hlsl
	@mkdir -p build
	$(DXC) $(FLAGS) -T ps_6_0 -E main $< -Fo $@ --depfile build/post.d

-include build/post.d
```

`make`, then `cat build/post.d`, then `make` again:

```text
oneshader -spirv -O3 -HV 2021 -WX -I shaders/common -D EXPOSURE=1.5 -T ps_6_0 -E main shaders/post.hlsl -Fo build/post.spv --depfile build/post.d
build/post.spv: /tmp/oneshader-docs/cookbook/Dxc/shaders/post.hlsl /tmp/oneshader-docs/cookbook/Dxc/shaders/common/color.hlsli
make: 'build/post.spv' is up to date.
```

After `touch shaders/common/color.hlsli`, `make` compiles again. The output passes `spirv-val`, and DXC compiles the same command line (without `--depfile`) too.

## The flags

From the tool’s documentation, checked against `oneshader --help` 1.2.0:

| DXC flag | In oneshader |
|---|---|
| `-T <profile>` | `vs_6_x`, `ps_6_x`, `cs_6_x` (also `_5_x`). The stage comes from the profile; the model number is accepted and otherwise unused. |
| `-E <name>` | Entry point. With `-T` and no `-E` it’s `main`, as in DXC. |
| `-D NAME[=VALUE]`, `-I <dir>` | As in DXC. |
| `-Fo <file>` | Output file. With several entry points or targets, the names are derived from it (`name.<entry>.spv`, `.metal`, `.wgsl`). Without `-Fo`, a single output goes to standard output. |
| `-spirv` | SPIR-V, which is also the default. (DXC’s default is DXIL, which oneshader doesn’t write.) |
| `-O0`, `-Od`, `-O1`..`-O3` | Optimizer off or on (on by default). |
| `-Zpr`, `-Zpc` | Row-major or column-major default matrix packing. |
| `-HV 2021` | Accepted (`202x` too). Other versions are rejected. |
| `-WX` | Warnings are errors. |
| `-enable-16bit-types` | `half`, `min16*` and the `int16_t` family are native 16-bit types, as in DXC (since 1.2.0). See [16-bit and 64-bit types](https://recursiveai.org/oneshader/cookbook/hlsl-16-bit-64-bit-types/). |
| `-fspv-target-env=vulkan1.2` | Accepted (`vulkan1.3` too). The output is valid for Vulkan 1.2 and newer. |
| `-nologo` | Accepted and ignored. |

What oneshader adds:

| Option | Meaning |
|---|---|
| `--target spirv\|msl\|wgsl` | Target; repeat for several. |
| `--all-entries` | Compile every `[shader("vertex"\|"pixel"\|"compute")]` entry point. Also what happens without `-T`. |
| `--reflect <file.json>` | Reflection as JSON, deterministic and without machine paths. See [Read shader reflection](https://recursiveai.org/oneshader/cookbook/spirv-reflection-csharp/). |
| `--depfile <file>` | A Make-style dependency file, written on success. |
| `--no-names` | Leave source names out of the output. |

Diagnostics go to standard error as `file(line,col): error OSHnnnn: message`, the form IDEs and CMake parse. The exit code is 0 for success, 1 when the shader doesn’t compile, 2 for a wrong command line.

## What it rejects

Every other `-fvk-*` and `-fspv-*` option, and DXC options such as `-Zi` or `-Fh`, stop with a message that names the option (exit code 2):

```text
oneshader: error: option '-Zi' is not supported: debug info is not implemented. Remove it, or use --no-names to drop names from the output. Run 'oneshader --help' for the options.
oneshader: error: option '-fvk-use-dx-layout' is not supported. oneshader always uses DXC's default Vulkan layout and binding rules; use [[vk::binding]], [[vk::location]] and [[vk::offset]] in the shader instead. Run 'oneshader --help' for the options.
oneshader: error: -T gs_6_0 is not a supported profile. Use vs_6_x, ps_6_x or cs_6_x; geometry, tessellation, mesh and library profiles are not supported. Run 'oneshader --help' for the options.
```

- **Layout and binding remapping** (`-fvk-b-shift`, `-fvk-use-dx-layout` and the like) isn’t supported. oneshader always applies DXC’s default Vulkan rules, so move the numbers into the shader with `[[vk::binding]]`, `[[vk::location]]` and `[[vk::offset]]`.
- **DXIL**, and geometry, tessellation, mesh, ray-tracing and library profiles, aren’t supported. Keep DXC for those.

## Speed

Started once per shader, as in a Makefile, the tool’s speed depends on how it’s built. The repository measures a NativeAOT build at about 2.4 times faster than DXC’s release binary per process, warm. Run as an ordinary .NET process, like the .NET tool installed above, it’s slower than DXC: about 6 times with ReadyToRun and 14 times with the JIT, because starting the runtime dominates a compile that takes 0.34 ms at the median. To get the NativeAOT binary, publish it from the repository with `dotnet publish src/OneShader.Tool -c Release -r linux-x64 -o out`. The numbers and the method are in [Performance against DXC](https://recursiveai.org/oneshader/docs/performance/).

How DXC, glslang and OneShader differ on bindings and target environments: [HLSL to SPIR-V compiler compared](https://recursiveai.org/oneshader/articles/hlsl-to-spirv-compiler/).
