Navigate to the top level

Surface_as_vertex_array

Description
Tests rendering to GPU surfaces (render targets) and subsequently binding the rendered surface memory as a vertex attribute array (vertex stream).
This pattern takes advantage of Xbox UMA (Unified Memory Architecture) to perform GPU-driven vertex generation or displacement mapping without hardware vertex texture fetch.
Suite class def

DownloadByCPURead

Writes red into the first row of a linear surface with the CPU and draws the top two quads using it as the diffuse stream. Green is then rendered over the same memory, the GPU is idled, and the CPU reads a pixel from the surface (displayed at the top of the screen; expect 0xFF00FF00). The bottom two quads are then drawn from the same diffuse stream. Expect to see two red quads on top and two green quads on the bottom. Reproduces xemu #859: on xemu, the CPU read triggers a surface download that does not mark the renderer's copy of VRAM as dirty, so the bottom quads are drawn with the stale red vertex colors.

Image with alpha
Test result for Surface_as_vertex_array::DownloadByCPURead
Image as seen on display
No alpha test result for Surface_as_vertex_array::DownloadByCPURead

DownloadByTextureRead

As DownloadByCPURead, but instead of a CPU read the rendered surface memory is sampled as a 16x2 linear A8R8G8B8 texture (only the first row is displayed) whose dimensions do not match the surface, drawn as a strip between the quad rows. Expect to see two red quads on top, a green strip in the middle, and two green quads on the bottom. Reproduces xemu #859: on xemu, the incompatible texture triggers a surface download that does not mark the renderer's copy of VRAM as dirty, so the strip is green but the bottom quads are drawn with stale red vertex colors.

Image with alpha
Test result for Surface_as_vertex_array::DownloadByTextureRead
Image as seen on display
No alpha test result for Surface_as_vertex_array::DownloadByTextureRead

DynamicUpdateLoop

Sequentially renders a single color into a surface and immediately draws the corresponding quad in four successive passes within a single frame to verify surface update synchronization between draw passes. Expect to see four quads on a dark background: top-left Red, top-right Green, bottom-left Blue, bottom-right Yellow.

Image with alpha
Test result for Surface_as_vertex_array::DynamicUpdateLoop
Image as seen on display
No alpha test result for Surface_as_vertex_array::DynamicUpdateLoop

ImageBlitOverVertexArray

Writes red into the first row of a buffer with the CPU and draws the top two quads using it as the diffuse stream. Green pixels written by the CPU into a second buffer are then copied over the first using an NV09F image blit (SRCCOPY), and the bottom two quads are drawn from the same diffuse stream. Expect to see two red quads on top and two green quads on the bottom. On xemu, the blit does not mark the renderer's copy of VRAM as dirty (the same issue as xemu #859, but not addressed by xemu PR #2800), so the bottom quads are drawn with the stale red vertex colors.

Image with alpha
Test result for Surface_as_vertex_array::ImageBlitOverVertexArray
Image as seen on display
No alpha test result for Surface_as_vertex_array::ImageBlitOverVertexArray

LinearDiffuseArray

Renders four solid color strips (Red, Green, Blue, Yellow) into the first row of a linear A8R8G8B8 surface. The surface memory is then bound as NV2A_VERTEX_ATTR_DIFFUSE with TYPE_UB_D3D format and drawn via DRAW_ARRAYS. Expect to see four quads on a dark background: top-left Red, top-right Green, bottom-left Blue, bottom-right Yellow.

Image with alpha
Test result for Surface_as_vertex_array::LinearDiffuseArray
Image as seen on display
No alpha test result for Surface_as_vertex_array::LinearDiffuseArray

MultiStream

Tests multiple simultaneous surface vertex streams. Surface A is rendered with Cyan and Black pixels and bound to NV2A_VERTEX_ATTR_DIFFUSE; Surface B is rendered with Black and Magenta pixels and bound to NV2A_VERTEX_ATTR_SPECULAR. A register combiner adds Diffuse and Specular colors. Expect to see two wide quads on a dark background: left Cyan (Cyan + Black) and right Magenta (Black + Magenta).

Image with alpha
Test result for Surface_as_vertex_array::MultiStream
Image as seen on display
No alpha test result for Surface_as_vertex_array::MultiStream

RenderScalePattern

Renders carrier triangle vertex indices and barycentric weights across swizzled surfaces A and B. The surfaces are bound as Diffuse and Specular vertex streams with a vertex shader that blends three carrier positions via address-register palette lookups (arl a0.x / c[A0+112]) to reconstruct a 3D mesh. Expect to see a clean, contiguous 3D mesh at 1x render scale. When emulator render scale > 1.0 downsamples/filters the surface with interpolation errors across diagonal seams, shifts in index values cause address-register lookups to select incorrect palette slots, visibly tearing the mesh into spikes (reproducing the behavior in the XDK DisplacementMap sample and xemu PR #2984).

Image with alpha
Test result for Surface_as_vertex_array::RenderScalePattern
Image as seen on display
No alpha test result for Surface_as_vertex_array::RenderScalePattern

SwizzledDiffuseArray

Renders four 2x2 color blocks into a swizzled A8R8G8B8 surface (paired with matching 32-bit depth buffer). Due to Morton order swizzling, the 2x2 blocks occupy contiguous 4-pixel chunks in memory. The surface is then bound as NV2A_VERTEX_ATTR_DIFFUSE. Expect to see four quads on a dark background: top-left Red, top-right Green, bottom-left Blue, bottom-right Yellow.

Image with alpha
Test result for Surface_as_vertex_array::SwizzledDiffuseArray
Image as seen on display
No alpha test result for Surface_as_vertex_array::SwizzledDiffuseArray