Skip to content

Commit 16e8efd

Browse files
authored
Merge branch 'main' into active-ballot
2 parents b9da42e + bda084e commit 16e8efd

File tree

73 files changed

+3499
-406
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3499
-406
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ endmacro()
4343

4444
find_package(Vulkan)
4545
message(STATUS "Vulkan Include Dirs: ${Vulkan_INCLUDE_DIRS}")
46-
if (Vulkan_INCLUDE_DIRS)
46+
if (Vulkan_INCLUDE_DIRS AND NOT OFFLOADTEST_WARP_ONLY)
4747
set(OFFLOADTEST_ENABLE_VULKAN On)
4848
endif ()
4949

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ Buffers:
8585
- Name: In2
8686
Format: Hex16
8787
Data: [ 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]
88+
- Name: Tex
89+
Format: Float32
90+
Channels: 4
91+
OutputProps:
92+
Width: 2
93+
Height: 2
94+
Depth: 1
95+
MipLevels: 2
96+
Data: [ 1.0, 0.0, 0.0, 1.0, # Mip 0 (2x2)
97+
0.0, 1.0, 0.0, 1.0,
98+
0.0, 0.0, 1.0, 1.0,
99+
1.0, 1.0, 1.0, 1.0,
100+
1.0, 1.0, 0.0, 1.0 ] # Mip 1 (1x1)
88101
- Name: Out1 # Buffer where our output will go
89102
Format: Float32
90103
Stride: 4

docs/MipMappedTextures.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Mipmapped Textures
2+
3+
The test suite supports textures with multiple mipmap levels. This allows
4+
verifying that the compiler correctly generates code for
5+
`CalculateLevelOfDetail`, `SampleGrad` (explicit gradients), and direct access
6+
via `mips[level][coords]`.
7+
8+
## Defining Mip Levels
9+
10+
To define a texture with multiple mips, specify the `MipLevels` field in
11+
`OutputProps`.
12+
13+
**Example:**
14+
```yaml
15+
Buffers:
16+
- Name: Tex
17+
Format: Float32
18+
Channels: 4
19+
OutputProps:
20+
Width: 4
21+
Height: 4
22+
Depth: 1
23+
MipLevels: 3 # Defines Mip 0 (4x4), Mip 1 (2x2), and Mip 2 (1x1)
24+
```
25+
26+
## Dimension Calculation
27+
28+
The dimensions of each mip level are calculated automatically based on the base
29+
`Width`, `Height`, and `Depth` provided in `OutputProps`. Following standard
30+
graphics API conventions (Vulkan, DirectX, Metal), each subsequent mip level is
31+
half the size of the previous level, rounded down, with a minimum of 1.
32+
33+
For Mip Level $N$:
34+
* $\text{Width}_N = \max(1, \lfloor \text{Width}_0 / 2^N \rfloor)$
35+
* $\text{Height}_N = \max(1, \lfloor \text{Height}_0 / 2^N \rfloor)$
36+
* $\text{Depth}_N = \max(1, \lfloor \text{Depth}_0 / 2^N \rfloor)$
37+
38+
## Data Layout
39+
40+
The `Data` array in the YAML must contain the texel data for **all mip levels
41+
sequentially**, packed tightly without padding.
42+
43+
For a 4x4 texture with 3 mip levels, the `Data` array structure is:
44+
45+
1. **Mip 0 (4x4 = 16 texels):** Indices 0 - 15.
46+
2. **Mip 1 (2x2 = 4 texels):** Indices 16 - 19.
47+
3. **Mip 2 (1x1 = 1 texel):** Index 20.
48+
49+
**Total Size:** 21 texels.
50+
51+
### Example YAML
52+
53+
```yaml
54+
- Name: Tex
55+
Format: Float32
56+
Channels: 4 # RGBA
57+
OutputProps: { Width: 4, Height: 4, Depth: 1, MipLevels: 3 }
58+
Data: [
59+
# --- Mip 0 (4x4) ---
60+
1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, # Row 0 (Red)
61+
1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, # Row 1
62+
1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, # Row 2
63+
1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, # Row 3
64+
65+
# --- Mip 1 (2x2) ---
66+
0,1,0,1, 0,1,0,1, # Row 0 (Green)
67+
0,1,0,1, 0,1,0,1, # Row 1
68+
69+
# --- Mip 2 (1x1) ---
70+
0,0,1,1 # Single Pixel (Blue)
71+
]
72+
```
73+
74+
## Usage in Tests
75+
76+
This structure allows you to verify explicit mip selection in shaders:
77+
78+
```hlsl
79+
// Should return Green (Mip 1)
80+
float4 val = Tex.mips[1][int2(0,0)];
81+
82+
// Should return Blue (Mip 2)
83+
float4 val2 = Tex.Load(int3(0,0,2));
84+
```
85+
86+
## Implementation Notes
87+
88+
### Mipmap Filtering
89+
90+
Currently, the test suite hardcodes the mipmap sampling mode to **Nearest**
91+
(`VK_SAMPLER_MIPMAP_MODE_NEAREST` in Vulkan). This ensures deterministic results
92+
for tests that verify specific mip level selection without requiring linear
93+
interpolation between levels. Linear mip filtering is not configurable via YAML.

docs/WARP.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ will generate test targets for `check-hlsl-warp-d3d12` and
1111
There are some useful CMake options to tweak the configuration to better utilize
1212
WARP:
1313

14-
* **OFFLOADTEST_WARP_ONLY** - Skips generating d3d test configurations for
15-
non-WARP configurations. This is useful if you're running Windows in a VM and
16-
do not have a physical GPU.
14+
* **OFFLOADTEST_WARP_ONLY** - Skips generating non-WRAP test configurations
15+
and backends. This is useful if you're running Windows in a VM and only
16+
have a working WARP implementation.
1717

1818
* **WARP_VERSION** - Defaults to `LKG` which uses a Known-Good version of WARP.
1919
This is the default version tested in the GitHub actions. Alternatively this

include/Support/Pipeline.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ struct OutputProperties {
101101
int Height;
102102
int Width;
103103
int Depth;
104+
int MipLevels = 1;
104105
};
105106

106107
static inline uint32_t getFormatSize(DataFormat Format) {

lib/API/DX/Device.cpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,16 @@ static DXResourceKind getDXKind(offloadtest::ResourceKind RK) {
156156
llvm_unreachable("All cases handled");
157157
}
158158

159-
static D3D12_RESOURCE_DESC getResourceDescription(const Resource &R) {
159+
static llvm::Expected<D3D12_RESOURCE_DESC>
160+
getResourceDescription(const Resource &R) {
160161
const D3D12_RESOURCE_DIMENSION Dimension = getDXDimension(R.Kind);
161162
const offloadtest::Buffer &B = *R.BufferPtr;
163+
164+
if (B.OutputProps.MipLevels != 1)
165+
return llvm::createStringError(std::errc::not_supported,
166+
"Multiple mip levels are not yet supported "
167+
"for DirectX textures.");
168+
162169
const DXGI_FORMAT Format =
163170
R.isTexture() ? getDXFormat(B.Format, B.Channels) : DXGI_FORMAT_UNKNOWN;
164171
const uint32_t Width =
@@ -611,7 +618,10 @@ class DXDevice : public offloadtest::Device {
611618
llvm::Expected<ResourceBundle> createSRV(Resource &R, InvocationState &IS) {
612619
ResourceBundle Bundle;
613620

614-
const D3D12_RESOURCE_DESC ResDesc = getResourceDescription(R);
621+
auto ResDescOrErr = getResourceDescription(R);
622+
if (!ResDescOrErr)
623+
return ResDescOrErr.takeError();
624+
const D3D12_RESOURCE_DESC ResDesc = *ResDescOrErr;
615625
const D3D12_HEAP_PROPERTIES UploadHeapProp =
616626
CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
617627
const D3D12_RESOURCE_DESC UploadResDesc =
@@ -708,7 +718,10 @@ class DXDevice : public offloadtest::Device {
708718
ResourceBundle Bundle;
709719
const uint32_t BufferSize = getUAVBufferSize(R);
710720

711-
const D3D12_RESOURCE_DESC ResDesc = getResourceDescription(R);
721+
auto ResDescOrErr = getResourceDescription(R);
722+
if (!ResDescOrErr)
723+
return ResDescOrErr.takeError();
724+
const D3D12_RESOURCE_DESC ResDesc = *ResDescOrErr;
712725

713726
const D3D12_HEAP_PROPERTIES ReadBackHeapProp =
714727
CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK);
@@ -1314,6 +1327,11 @@ class DXDevice : public offloadtest::Device {
13141327
std::errc::invalid_argument,
13151328
"No render target bound for graphics pipeline.");
13161329
const Buffer &OutBuf = *P.Bindings.RTargetBufferPtr;
1330+
if (OutBuf.OutputProps.MipLevels != 1)
1331+
return llvm::createStringError(
1332+
std::errc::not_supported,
1333+
"Multiple mip levels are not yet supported for DirectX render "
1334+
"targets.");
13171335
D3D12_RESOURCE_DESC Desc = {};
13181336
Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
13191337
Desc.Width = OutBuf.OutputProps.Width;
@@ -1465,13 +1483,13 @@ class DXDevice : public offloadtest::Device {
14651483
IS.RTVHeap->GetCPUDescriptorHandleForHeapStart();
14661484
Device->CreateRenderTargetView(IS.RT.Get(), nullptr, RTVHandle);
14671485

1486+
IS.CmdList->SetGraphicsRootSignature(IS.RootSig.Get());
14681487
if (IS.DescHeap) {
14691488
ID3D12DescriptorHeap *const Heaps[] = {IS.DescHeap.Get()};
14701489
IS.CmdList->SetDescriptorHeaps(1, Heaps);
14711490
IS.CmdList->SetGraphicsRootDescriptorTable(
14721491
0, IS.DescHeap->GetGPUDescriptorHandleForHeapStart());
14731492
}
1474-
IS.CmdList->SetGraphicsRootSignature(IS.RootSig.Get());
14751493
IS.CmdList->SetPipelineState(IS.PSO.Get());
14761494

14771495
IS.CmdList->OMSetRenderTargets(1, &RTVHandle, false, nullptr);
@@ -1509,6 +1527,43 @@ class DXDevice : public offloadtest::Device {
15091527
const CD3DX12_TEXTURE_COPY_LOCATION SrcLoc(IS.RT.Get(), 0);
15101528

15111529
IS.CmdList->CopyTextureRegion(&DstLoc, 0, 0, 0, &SrcLoc, nullptr);
1530+
1531+
auto CopyBackResource = [&IS, this](ResourcePair &R) {
1532+
if (R.first->isTexture()) {
1533+
const offloadtest::Buffer &B = *R.first->BufferPtr;
1534+
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT Footprint{
1535+
0, CD3DX12_SUBRESOURCE_FOOTPRINT(
1536+
getDXFormat(B.Format, B.Channels), B.OutputProps.Width,
1537+
B.OutputProps.Height, 1,
1538+
B.OutputProps.Width * B.getElementSize())};
1539+
for (const ResourceSet &RS : R.second) {
1540+
if (RS.Readback == nullptr)
1541+
continue;
1542+
addReadbackBeginBarrier(IS, RS.Buffer);
1543+
const CD3DX12_TEXTURE_COPY_LOCATION DstLoc(RS.Readback.Get(),
1544+
Footprint);
1545+
const CD3DX12_TEXTURE_COPY_LOCATION SrcLoc(RS.Buffer.Get(), 0);
1546+
IS.CmdList->CopyTextureRegion(&DstLoc, 0, 0, 0, &SrcLoc, nullptr);
1547+
addReadbackEndBarrier(IS, RS.Buffer);
1548+
}
1549+
return;
1550+
}
1551+
for (const ResourceSet &RS : R.second) {
1552+
if (RS.Readback == nullptr)
1553+
continue;
1554+
addReadbackBeginBarrier(IS, RS.Buffer);
1555+
IS.CmdList->CopyResource(RS.Readback.Get(), RS.Buffer.Get());
1556+
addReadbackEndBarrier(IS, RS.Buffer);
1557+
}
1558+
};
1559+
1560+
for (auto &Table : IS.DescTables)
1561+
for (auto &R : Table.Resources)
1562+
CopyBackResource(R);
1563+
1564+
for (auto &R : IS.RootResources)
1565+
CopyBackResource(R);
1566+
15121567
return llvm::Error::success();
15131568
}
15141569

0 commit comments

Comments
 (0)