gfx-views-raster (2026-11-02, batch r4): stencil cube views, remaining integer views, separate-texture slot masks, viewport swizzles, provoking vertex¶
Branch claude/gfx-views-raster-2026-11-02-r4 (Mac, Metal, base ed33737). Contract: gfx.md section 13 ("Views and raster state").
What changed¶
- Stencil sampling of cube / cube array depth-stencil views:
- Before: the translator refused it ("stencil sampling of a texture of type 3 ...").
- Now: the view is declared
texturecube<uint>/texturecube_array<uint>and read throughStencilTexCube/StencilTexCubeArray. The face and texel come from the direction (cube_face/cube_texel, shared with the integer cube wrappers). - Integer 1D, 1D array, cube array and 2D multisample array textures:
- Declared with the matching integer texture type and read through
IntTex1D,IntTex1DArray,IntTexCubeArrayandIntTex2DMSArray. Only texel buffers and depth comparison keep the float declaration. - The wrappers'
calculate_*_lodnow returnfloat, as Metal's do. A TMML on a wrapper used to buildfloat2(float2, float2). - Buffer <-> texture copies of a 1D array treat the region's y / height as layers. Metal asserted on the y offset before.
- Depth / stencil / integer slot masks for separate textures (the r3 finding):
ShaderKey.sep_*_slotsandpipe_key.sep_*[2], filled bysep_slot_masksfrom the separate texture bindings. Geometry and tess stages get them throughstage_key_masks.- The translator applies them to the texture word of a separate pair (
sep_masks). - Before: a separate integer or stencil texture was declared float, a Metal validation error.
- SetViewportSwizzles:
- Recorded as
OP_VP_SWIZZLEand applied to the clip position by the last pre-raster stage (ShaderKey.vp_swizzle): vertex, tess eval, and the geometry pass-through function. - It uses viewport 0's swizzle. A program that selects another viewport with different swizzles still gets viewport 0's (logged once).
- SetProvokingVertexMode:
- Recorded as
OP_PROVOKING. Mode 1 (last) re-emits direct draws as lists with each primitive's last vertex first (pv_last_indices). - Mode 0 is Metal's own convention (first vertex, checked on the M5) and stays unchanged.
- Indirect draws and draws through the geometry / tess stage paths keep the first vertex (logged once).
- The 0 = first / 1 = last mapping is a hypothesis: it follows the Maxwell register, and the NVN enum isn't public.
obj.h:OP_VP_SWIZZLEandOP_PROVOKINGappended beforeOP_COUNT(enum only).mtl_priv.h:pipe_keyfields.mtl_stages.inc: one line instage_key_masks. All three are the orchestrator's approved ownership extension.TRANSLATOR_VERSION17 -> 18.
Tests¶
t_stencil_sample: cube and cube array D24S8 textures, each layer-face cleared to its own stencil value, sampled in seven directions.t_int_tex7-10:- 1D;
- a 1D array with per-layer uploads;
- a cube array (cube 1, face -Y);
- a 4x multisample array (layer 1 written by a draw).
t_sep_sampler3-4: an RGBA8UI texture and a stencil view at separate bindings. Without the masks the draw fails Metal validation.t_vp_swizzle(new): identity, -x, x <-> y, back to identity.t_provoking(new): a triangle list, a strip, an indexed strip with a restart and a line list, each in modes 0 and 1.t_xlate: pins for every new wrapper, each compiled by Metal (TEX, TLD4, TMML, TLD.MS.ARRAY).make -C gfx test: ALL TESTS PASSED. The LAS corpus still gives 5767 / 5767 / 5767.
Not verified on a title¶
None of the four titles reaches these paths in the scenes booted: no stencil cube view, no integer 1D / cube array / MS array view, no separate binding, no viewport swizzle, no provoking mode 1. The boots show no regression (integrator file).