fix(render3d): a refused pipeline is not retried every draw, and an evicted chunk is freed whole
gvk_pipeline_fast cached only pipelines it made, so one the driver refused was attempted again on every draw, each attempt building its key string and create structs anew; the refusal is cached too (a Vulkan program's variants are fixed when it is made, so it would fail the same way). stream_evict made a new chunk list per eviction and never freed the evicted chunks' records; it compacts the list in place and frees each evicted chunk with its data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6dd1810038
commit
70a92a8862
2 changed files with 15 additions and 6 deletions
|
|
@ -1903,8 +1903,9 @@ function gvk_pipeline_fast(render3d_st: mut Render3dState, p: int, m: Mesh, st:
|
||||||
return render3d_st.gvk_pc_pipe[k]
|
return render3d_st.gvk_pc_pipe[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# a pipeline the driver refused is remembered as 0 too: retried on every draw, each try built its
|
||||||
|
# key and its create structs again and gave none of them back
|
||||||
let pipe = gvk_pipeline(render3d_st, p, m, st, n_color, color_fmt, depth_fmt, samples)
|
let pipe = gvk_pipeline(render3d_st, p, m, st, n_color, color_fmt, depth_fmt, samples)
|
||||||
if pipe == 0 { return pipe }
|
|
||||||
push(render3d_st.gvk_pc_prog, p); push(render3d_st.gvk_pc_layout, layout); push(render3d_st.gvk_pc_state, state)
|
push(render3d_st.gvk_pc_prog, p); push(render3d_st.gvk_pc_layout, layout); push(render3d_st.gvk_pc_state, state)
|
||||||
push(render3d_st.gvk_pc_bias, bias); push(render3d_st.gvk_pc_pass, pass); push(render3d_st.gvk_pc_pipe, pipe)
|
push(render3d_st.gvk_pc_bias, bias); push(render3d_st.gvk_pc_pass, pass); push(render3d_st.gvk_pc_pipe, pipe)
|
||||||
if p < 4096 { render3d_st.gvk_pc_last[p] = len(render3d_st.gvk_pc_prog) - 1 }
|
if p < 4096 { render3d_st.gvk_pc_last[p] = len(render3d_st.gvk_pc_prog) - 1 }
|
||||||
|
|
|
||||||
|
|
@ -162,16 +162,24 @@ function stream_evict(render3d_st: mut Render3dState, s: Stream) -> void {
|
||||||
}
|
}
|
||||||
t = lo
|
t = lo
|
||||||
# everything wanted by the walk in progress stays whatever the threshold says
|
# everything wanted by the walk in progress stays whatever the threshold says
|
||||||
let kept = new []Chunk
|
# compacted in place, and an evicted chunk goes whole: a new list per eviction and the chunks'
|
||||||
|
# own records were never given back
|
||||||
|
var w = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < s.n {
|
while i < s.n {
|
||||||
let c = s.chunks[i]
|
let c = s.chunks[i]
|
||||||
if c.used >= t or c.used == render3d_st.stream_walk_no { push(kept, c) }
|
if c.used >= t or c.used == render3d_st.stream_walk_no {
|
||||||
else { if c.data != null { free(c.data) } }
|
s.chunks[w] = c
|
||||||
|
w += 1
|
||||||
|
} else {
|
||||||
|
if c.data != null { free(c.data) }
|
||||||
|
free(c)
|
||||||
|
}
|
||||||
i += 1
|
i += 1
|
||||||
}
|
}
|
||||||
s.chunks = kept
|
let ch = s.chunks
|
||||||
s.n = len(kept)
|
while len(ch) > w { List.pop(ch) }
|
||||||
|
s.n = w
|
||||||
for h in 0 .. STREAM_HASH { s.htab[h] = 0 }
|
for h in 0 .. STREAM_HASH { s.htab[h] = 0 }
|
||||||
i = 0
|
i = 0
|
||||||
while i < s.n { s.keys[i] = s.chunks[i].key; stream_remember(s, s.chunks[i].key, i); i += 1 }
|
while i < s.n { s.keys[i] = s.chunks[i].key; stream_remember(s, s.chunks[i].key, i); i += 1 }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue