mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
The record's copies put the count the game's culling pass wrote into the first dispatch and, without a task stage, into the draw's instances as it was. A garbage count launched up to millions of workgroups that write nothing and instances that draw nothing, enough to keep the GPU past the driver's timeout; with the fallback now the default on AMD's driver for RDNA 1 and 2, such a count would have moved a hang there instead of removing it. A single-thread compute pass (shaders/meshfb_clamp.comp) cuts the count to the buffers' room, which changes nothing that is drawn; the report word keeps the count asked for, so record_check still logs a mesh-only draw that asked for more than the buffers hold. On for every device that uses the fallback: one dispatch and one barrier per indirect fallback draw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
34 lines
2.5 KiB
C
34 lines
2.5 KiB
C
// The mesh fallback's buffers and its records (vk_mesh_fb.c); the modules are mesh_fb.c's, the draws
|
|
// vk_exec_draw.c's ("mesh fallback").
|
|
#pragma once
|
|
#include "vk.h"
|
|
|
|
// Creates the buffers and the scan pipeline on first use. 0 when that failed (logged once): the draws are skipped.
|
|
int vk_meshfb_init(void);
|
|
// The buffer a module's extra storage binding reads or writes (mesh_fb.h MESHFB_CB_*), whole or as much of it as one
|
|
// storage binding may span.
|
|
VkDescriptorBufferInfo vk_meshfb_buffer(int cb_slot);
|
|
uint64_t vk_meshfb_mesh_words(void); // the mesh buffer's size as a binding sees it, in words
|
|
|
|
// A draw's record, 64 bytes of the record buffer (*rec) at the offset returned: the task dispatch at +0, the mesh
|
|
// dispatch at +16, the draw (VkDrawIndirectCommand) at +32. Records the fills and copies that start it, outside a
|
|
// pass: the workgroup count from 4 bytes at src_off of src, or `count` when src is VK_NULL_HANDLE. Without a task
|
|
// stage that count is the mesh dispatch and the draw's instance count; with one it is the task dispatch, and
|
|
// vk_meshfb_scan writes the rest. slot_words: of the draw's mesh program, for the report of a draw the mesh buffer
|
|
// was too small for. Returns the number of commands recorded in *cmds.
|
|
VkDeviceSize vk_meshfb_record(VkCommandBuffer cb, VkBuffer src, VkDeviceSize src_off, uint32_t count, int has_task,
|
|
uint32_t verts, uint32_t slot_words, VkBuffer *rec, int *cmds);
|
|
// For a record whose count came from src (a count the GPU wrote): cuts it to what the buffers hold, in the task dispatch
|
|
// (task_words, the task stage's payload words) or without a task stage (0) in the mesh dispatch and the instances
|
|
// (shaders/meshfb_clamp.comp). Binds its own compute pipeline and set; four commands, between two barriers.
|
|
void vk_meshfb_clamp(VkCommandBuffer cb, VkDeviceSize at, uint32_t task_words);
|
|
// The pass between the task and the mesh dispatch (shaders/meshfb_scan.comp): binds its own compute pipeline and set.
|
|
void vk_meshfb_scan(VkCommandBuffer cb, VkDeviceSize at, uint32_t task_words, uint32_t fan, uint32_t slot_words, uint32_t verts);
|
|
// After the record is complete (the copies or the scan, and a barrier): keeps what the draw asked for where the host
|
|
// reads it later. One copy command.
|
|
void vk_meshfb_note(VkCommandBuffer cb, VkDeviceSize at);
|
|
// Draws so far whose programs emitted more than the buffers hold, the records not looked at yet included: call it
|
|
// with the device idle (a probe, the shutdown).
|
|
uint64_t vk_meshfb_short(void);
|
|
void vk_meshfb_shutdown(void); // the device must be idle
|