Skip to content

[Vulkan][DirectX] Add support for array textures, starting with Texture2DArray and RWTexture2DArray - #1468

Open
Icohedron wants to merge 7 commits into
users/icohedron/texture-refactorfrom
users/icohedron/texture2darray
Open

[Vulkan][DirectX] Add support for array textures, starting with Texture2DArray and RWTexture2DArray#1468
Icohedron wants to merge 7 commits into
users/icohedron/texture-refactorfrom
users/icohedron/texture2darray

Conversation

@Icohedron

@Icohedron Icohedron commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for array textures in the VK and DX backends.

To start with, only Texture2DArray and RWTexture2DArray are supported.

The remaining array texture types will be added in subsequent PRs.

This PR also fixes some of incorrectly-linked XFAILs in texture tests, and adds some missing docs about UAVs for mipmapped textures that also apply to array textures.

I also snuck in tests for RWTexture2D since we are implementing RWTexture2DArray with this PR anyways.

Assisted by: Claude Opus 5


Stack created with GitHub Stacks CLIGive Feedback 💬

…rray

Introduces the Texture2DArray and RWTexture2DArray resource kinds and the
plumbing they need to be described, validated and laid out, without wiring
them into any back-end yet.

  - OutputProperties gains ArraySlices (default 1). Buffer size validation
    multiplies the mip chain by the slice count.
  - Array texture data is laid out slice-major: the full mip chain of slice 0,
    then slice 1, and so on. This matches D3D12's `Mip + Slice * MipLevels`
    subresource indexing, so the same YAML feeds every back-end.
    computeTightTextureUploadLayout() emits one footprint per (mip, slice).
  - TextureCreateDesc gains ArraySlices and IsArray. IsArray is not derivable
    from the slice count: a Texture2DArray with a single slice still needs an
    array-typed view.
  - Resources are validated at parse time: ArraySlices may only exceed 1 for
    an array kind, and must be at least 1.

Adding a ResourceKind means every exhaustive switch over it has to handle the
new values, so the descriptor and image-view mappings are filled in here and
Metal asserts on the kinds it cannot create. Creating and copying layered
images is left to the per-back-end commits that follow.

Assisted by: Claude Opus 5
Describes the slice count on the resource and selects array-typed views:

  - getDXResourceDesc() sets DepthOrArraySize from ArraySlices, which is what
    makes GetCopyableFootprints report the per-(mip, slice) subresources that
    the upload and readback paths already walk.
  - SRV and UAV creation pick TEXTURE2DARRAY over TEXTURE2D based on IsArray,
    filling in FirstArraySlice/ArraySize.

Assisted by: Claude Opus 5
Maps the new kinds onto layered 2D images:

  - Images are created with arrayLayers taken from the slice count, and image
    views expose every layer.
  - Copy regions and barriers iterate (slice, mip) rather than mip alone, so
    uploads and readbacks address each subresource individually. Vulkan
    staging buffers stay tightly packed and slice-major, matching the layout
    the harness produces.

Assisted by: Claude Opus 5
@Icohedron Icohedron linked an issue Aug 24, 2026 that may be closed by this pull request
2 tasks

@bob80905 bob80905 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall excellent contribution imo, just a couple things. None are blocking.

Comment thread lib/Support/Pipeline.cpp
I.setError(Twine("Referenced buffer ") + R.Name + " not found!");
}
if (R.BufferPtr)
if (auto Err = validateTextureResource(R))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SUGGESTION]: The convention here seems to be to check the resource type before validating for that type. You've baked in the texture type check into the validation function, but why not check whether the resource is a texture type, and if so, then call the validation function?
So something like if (R.BufferPtr && R.isTexture()) ?

float4 mainPS(float4 Pos : SV_POSITION) : SV_Target {
uint2 GTid = (uint2)Pos.xy;

// Texture2DArray::CalculateLevelOfDetail takes a **float2**, not the float3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It may be possible to make this comment less verbose.

Out[6] = Tex.SampleLevel(BorderSamp, float3(1.25, 0.5, 1), 0); // -> border
Out[7] = Tex.SampleLevel(MirrorSamp, float3(1.75, 0.5, 1), 0); // -> Blue

// The slice coordinate is *not* subject to the address mode: it is always

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise with this comment.


[numthreads(1, 1, 1)]
void main() {
// Every slice carries its own mip chain. Slice 0 is mip 0 [Red, Green] over

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, generally might be worth doing a light comment skim and making sure they're trimmed and concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tests for Texture2DArray Add tests for RWTexture2DArray Add tests for RWTexture2D [SPIRV][DirectX] Add Texture*Array type support

2 participants