mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-18 04:00:32 +01:00
llvmpipe/fs: fix multisample depth/stencil fs writes.
The state wasn't storing the shader depth/stencil outputs
per-sample, so only the last sample emitted was being used
for the late depth test and stencil ref.
Noticed while trying to fix some vulkan depth stencil resolve
issues
Fixes: a0195240c4 ("llvmpipe: handle multisample early depth test/late depth write")
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12504>
This commit is contained in:
parent
6c75e5e3c6
commit
291d0795a3
1 changed files with 53 additions and 10 deletions
|
|
@ -589,6 +589,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
LLVMValueRef stencil_refs[2];
|
||||
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
|
||||
LLVMValueRef zs_samples = lp_build_const_int32(gallivm, key->zsbuf_nr_samples);
|
||||
LLVMValueRef z_out = NULL, s_out = NULL;
|
||||
struct lp_build_for_loop_state loop_state, sample_loop_state = {0};
|
||||
struct lp_build_mask_context mask;
|
||||
/*
|
||||
|
|
@ -700,6 +701,17 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
color_store_size, "color1");
|
||||
}
|
||||
}
|
||||
if (shader->info.base.writes_z) {
|
||||
z_out = lp_build_array_alloca(gallivm,
|
||||
lp_build_vec_type(gallivm, type),
|
||||
color_store_size, "depth");
|
||||
}
|
||||
|
||||
if (shader->info.base.writes_stencil) {
|
||||
s_out = lp_build_array_alloca(gallivm,
|
||||
lp_build_vec_type(gallivm, type),
|
||||
color_store_size, "depth");
|
||||
}
|
||||
|
||||
lp_build_for_loop_begin(&loop_state, gallivm,
|
||||
lp_build_const_int32(gallivm, 0),
|
||||
|
|
@ -1049,6 +1061,33 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
LLVMBuildStore(builder, output_smask, out_sample_mask_storage);
|
||||
}
|
||||
|
||||
if (shader->info.base.writes_z) {
|
||||
int pos0 = find_output_by_semantic(&shader->info.base,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
0);
|
||||
LLVMValueRef out = LLVMBuildLoad(builder, outputs[pos0][2], "");
|
||||
LLVMValueRef idx = loop_state.counter;
|
||||
if (key->min_samples > 1)
|
||||
idx = LLVMBuildAdd(builder, idx,
|
||||
LLVMBuildMul(builder, sample_loop_state.counter, num_loop, ""), "");
|
||||
LLVMValueRef ptr = LLVMBuildGEP(builder, z_out, &idx, 1, "");
|
||||
LLVMBuildStore(builder, out, ptr);
|
||||
}
|
||||
|
||||
if (shader->info.base.writes_stencil) {
|
||||
int sten_out = find_output_by_semantic(&shader->info.base,
|
||||
TGSI_SEMANTIC_STENCIL,
|
||||
0);
|
||||
LLVMValueRef out = LLVMBuildLoad(builder, outputs[sten_out][1], "output.s");
|
||||
LLVMValueRef idx = loop_state.counter;
|
||||
if (key->min_samples > 1)
|
||||
idx = LLVMBuildAdd(builder, idx,
|
||||
LLVMBuildMul(builder, sample_loop_state.counter, num_loop, ""), "");
|
||||
LLVMValueRef ptr = LLVMBuildGEP(builder, s_out, &idx, 1, "");
|
||||
LLVMBuildStore(builder, out, ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Color write - per fragment sample */
|
||||
for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
|
||||
{
|
||||
|
|
@ -1119,14 +1158,13 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
|
||||
/* Late Z test */
|
||||
if (depth_mode & LATE_DEPTH_TEST) {
|
||||
int pos0 = find_output_by_semantic(&shader->info.base,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
0);
|
||||
int s_out = find_output_by_semantic(&shader->info.base,
|
||||
TGSI_SEMANTIC_STENCIL,
|
||||
0);
|
||||
if (pos0 != -1 && outputs[pos0][2]) {
|
||||
z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
|
||||
if (shader->info.base.writes_z) {
|
||||
LLVMValueRef idx = loop_state.counter;
|
||||
if (key->min_samples > 1)
|
||||
idx = LLVMBuildAdd(builder, idx,
|
||||
LLVMBuildMul(builder, sample_loop_state.counter, num_loop, ""), "");
|
||||
LLVMValueRef ptr = LLVMBuildGEP(builder, z_out, &idx, 1, "");
|
||||
z = LLVMBuildLoad(builder, ptr, "output.z");
|
||||
} else {
|
||||
if (key->multisample) {
|
||||
lp_build_interp_soa_update_pos_dyn(interp, gallivm, loop_state.counter, key->multisample ? sample_loop_state.counter : NULL);
|
||||
|
|
@ -1148,10 +1186,15 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
lp_build_const_vec(gallivm, type, 1.0));
|
||||
}
|
||||
|
||||
if (s_out != -1 && outputs[s_out][1]) {
|
||||
if (shader->info.base.writes_stencil) {
|
||||
LLVMValueRef idx = loop_state.counter;
|
||||
if (key->min_samples > 1)
|
||||
idx = LLVMBuildAdd(builder, idx,
|
||||
LLVMBuildMul(builder, sample_loop_state.counter, num_loop, ""), "");
|
||||
LLVMValueRef ptr = LLVMBuildGEP(builder, s_out, &idx, 1, "");
|
||||
stencil_refs[0] = LLVMBuildLoad(builder, ptr, "output.s");
|
||||
/* there's only one value, and spec says to discard additional bits */
|
||||
LLVMValueRef s_max_mask = lp_build_const_int_vec(gallivm, int_type, 255);
|
||||
stencil_refs[0] = LLVMBuildLoad(builder, outputs[s_out][1], "output.s");
|
||||
stencil_refs[0] = LLVMBuildBitCast(builder, stencil_refs[0], int_vec_type, "");
|
||||
stencil_refs[0] = LLVMBuildAnd(builder, stencil_refs[0], s_max_mask, "");
|
||||
stencil_refs[1] = stencil_refs[0];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue