gallium/draw: Enable aapoint NIR helpers to generate bool1, bool32, or float32 Booleans

Fixes arb_point_parameters-point-attenuation on G33. The crash in
point-line-no-cull is fixed, but the test still fails.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20869>
This commit is contained in:
Ian Romanick 2023-01-23 14:46:57 -08:00
parent 17b610771d
commit d3a95f0f71
9 changed files with 85 additions and 21 deletions

View file

@ -39,6 +39,7 @@
#include "pipe/p_state.h"
#include "nir.h"
struct pipe_context;
struct draw_context;
@ -130,7 +131,8 @@ boolean
draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe);
boolean
draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe);
draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe,
nir_alu_type bool_type);
boolean
draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe);

View file

@ -99,6 +99,9 @@ struct aapoint_stage
/** vertex attrib slot containing position */
uint pos_slot;
/** Type of Boolean variables on this hardware. */
nir_alu_type bool_type;
/** Currently bound fragment shader */
struct aapoint_fragment_shader *fs;
@ -418,7 +421,7 @@ generate_aapoint_fs_nir(struct aapoint_stage *aapoint)
if (!aapoint_fs.ir.nir)
return FALSE;
nir_lower_aapoint_fs(aapoint_fs.ir.nir, &aapoint->fs->generic_attrib);
nir_lower_aapoint_fs(aapoint_fs.ir.nir, &aapoint->fs->generic_attrib, aapoint->bool_type);
aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(pipe, &aapoint_fs);
if (aapoint->fs->aapoint_fs == NULL)
goto fail;
@ -689,7 +692,7 @@ draw_aapoint_prepare_outputs(struct draw_context *draw,
static struct aapoint_stage *
draw_aapoint_stage(struct draw_context *draw)
draw_aapoint_stage(struct draw_context *draw, nir_alu_type bool_type)
{
struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
if (!aapoint)
@ -704,6 +707,7 @@ draw_aapoint_stage(struct draw_context *draw)
aapoint->stage.flush = aapoint_flush;
aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
aapoint->stage.destroy = aapoint_destroy;
aapoint->bool_type = bool_type;
if (!draw_alloc_temp_verts(&aapoint->stage, 4))
goto fail;
@ -793,7 +797,8 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
*/
boolean
draw_install_aapoint_stage(struct draw_context *draw,
struct pipe_context *pipe)
struct pipe_context *pipe,
nir_alu_type bool_type)
{
struct aapoint_stage *aapoint;
@ -802,7 +807,7 @@ draw_install_aapoint_stage(struct draw_context *draw,
/*
* Create / install AA point drawing / prim stage
*/
aapoint = draw_aapoint_stage(draw);
aapoint = draw_aapoint_stage(draw, bool_type);
if (!aapoint)
return FALSE;

View file

@ -300,8 +300,8 @@ nir_lower_aapoint_block(nir_block *block,
}
static void
nir_lower_aapoint_impl(nir_function_impl *impl,
lower_aapoint *state)
nir_lower_aapoint_impl(nir_function_impl *impl, lower_aapoint *state,
nir_alu_type bool_type)
{
nir_builder *b = &state->b;
@ -317,7 +317,21 @@ nir_lower_aapoint_impl(nir_function_impl *impl,
nir_ssa_def *k = nir_channel(b, aainput, 2);
nir_ssa_def *chan_val_one = nir_channel(b, aainput, 3);
nir_ssa_def *comp = nir_flt32(b, chan_val_one, dist);
nir_ssa_def *comp;
switch (bool_type) {
case nir_type_bool1:
comp = nir_flt(b, chan_val_one, dist);
break;
case nir_type_bool32:
comp = nir_flt32(b, chan_val_one, dist);
break;
case nir_type_float32:
comp = nir_slt(b, chan_val_one, dist);
break;
default:
unreachable("Invalid Boolean type.");
}
nir_discard_if(b, comp);
b->shader->info.fs.uses_discard = true;
@ -339,7 +353,41 @@ nir_lower_aapoint_impl(nir_function_impl *impl,
* else
* sel = 1.0;
*/
nir_ssa_def *sel = nir_b32csel(b, nir_fge32(b, k, dist), coverage, chan_val_one);
nir_ssa_def *sel;
switch (bool_type) {
case nir_type_bool1:
sel = nir_b32csel(b, nir_fge(b, k, dist), coverage, chan_val_one);
break;
case nir_type_bool32:
sel = nir_b32csel(b, nir_fge32(b, k, dist), coverage, chan_val_one);
break;
case nir_type_float32: {
/* On this path, don't assume that any "fancy" instructions are
* supported, but also try to emit something decent.
*
* sel = (k >= distance) ? coverage : 1.0;
* sel = (k >= distance) * coverage : (1 - (k >= distance)) * 1.0
* sel = (k >= distance) * coverage : (1 - (k >= distance))
*
* Since (k >= distance) * coverage is zero when (1 - (k >= distance))
* is not zero,
*
* sel = (k >= distance) * coverage + (1 - (k >= distance))
*
* If we assume that coverage == fsat(coverage), this could be further
* optimized to fsat(coverage + (1 - (k >= distance))), but I don't feel
* like verifying that right now.
*/
nir_ssa_def *cmp_result = nir_sge(b, k, dist);
sel = nir_fadd(b,
nir_fmul(b, coverage, cmp_result),
nir_fadd(b, chan_val_one, nir_fneg(b, cmp_result)));
break;
}
default:
unreachable("Invalid Boolean type.");
}
nir_foreach_block(block, impl) {
nir_lower_aapoint_block(block, state, sel);
@ -347,8 +395,12 @@ nir_lower_aapoint_impl(nir_function_impl *impl,
}
void
nir_lower_aapoint_fs(struct nir_shader *shader, int *varying)
nir_lower_aapoint_fs(struct nir_shader *shader, int *varying, const nir_alu_type bool_type)
{
assert(bool_type == nir_type_bool1 ||
bool_type == nir_type_bool32 ||
bool_type == nir_type_float32);
lower_aapoint state = {
.shader = shader,
};
@ -378,7 +430,7 @@ nir_lower_aapoint_fs(struct nir_shader *shader, int *varying)
nir_foreach_function(function, shader) {
if (function->impl) {
nir_lower_aapoint_impl(function->impl, &state);
nir_lower_aapoint_impl(function->impl, &state, bool_type);
}
}
}

View file

@ -43,7 +43,8 @@ nir_lower_aaline_fs(struct nir_shader *shader, int *varying,
nir_variable *stipple_pattern);
void
nir_lower_aapoint_fs(struct nir_shader *shader, int *varying);
nir_lower_aapoint_fs(struct nir_shader *shader, int *varying,
nir_alu_type bool_type);
#ifdef __cplusplus
}

View file

@ -203,8 +203,8 @@ spec@!opengl 1.1@linestipple@Factor 3x,Fail
spec@!opengl 1.1@linestipple@Line loop,Fail
spec@!opengl 1.1@linestipple@Line strip,Fail
# "../src/compiler/nir/nir_lower_int_to_float.c:102: lower_alu_instr: Assertion `nir_alu_type_get_base_type(info->output_type) != nir_type_int && nir_alu_type_get_base_type(info->output_type) != nir_type_uint' failed."
spec@!opengl 1.1@point-line-no-cull,Crash
# Test no longer crashes on an assertion in NIR, but it still fails.
spec@!opengl 1.1@point-line-no-cull,Fail
spec@!opengl 1.1@polygon-mode-offset,Fail
spec@!opengl 1.1@polygon-mode-offset@config 3: Expected white pixel on bottom edge,Fail
@ -403,9 +403,6 @@ spec@arb_pixel_buffer_object@cubemap npot pbo,Fail
spec@arb_pixel_buffer_object@fbo-pbo-readpixels-small,Fail
spec@arb_pixel_buffer_object@pbo-getteximage,Fail
# nir_lower_aapoint_impl() uses b32csel instead of fcsel.
spec@arb_point_parameters@arb_point_parameters-point-attenuation,Crash
spec@arb_point_parameters@arb_point_parameters-point-attenuation@Aliased combinations,Fail
spec@arb_provoking_vertex@arb-provoking-vertex-render,Fail
spec@arb_sampler_objects@gl_ext_texture_srgb_decode,Fail

View file

@ -237,7 +237,7 @@ i915_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
i915->no_log_program_errors = false;
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base, nir_type_float32);
draw_enable_point_sprites(i915->draw, true);
i915->dirty = ~0;

View file

@ -303,7 +303,7 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv,
/* plug in AA line/point stages */
draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe);
draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe);
draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe, nir_type_bool32);
draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
/* convert points and lines into triangles:

View file

@ -54,6 +54,8 @@
#include "sp_tex_sample.h"
#include "sp_image.h"
#include "nir.h"
static void
softpipe_destroy( struct pipe_context *pipe )
{
@ -321,7 +323,7 @@ softpipe_create_context(struct pipe_screen *screen,
/* plug in AA line/point stages */
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe, nir_type_bool32);
/* Do polygon stipple w/ texture map + frag prog. */
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);

View file

@ -182,6 +182,11 @@ svga_init_swtnl(struct svga_context *svga)
/* must be done before installing Draw stages */
util_blitter_cache_all_shaders(svga->blitter);
const nir_alu_type bool_type =
screen->screen.get_shader_param(&screen->screen, PIPE_SHADER_FRAGMENT,
PIPE_SHADER_CAP_INTEGERS) ?
nir_type_bool32 : nir_type_float32;
if (!screen->haveLineSmooth)
draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
@ -189,7 +194,7 @@ svga_init_swtnl(struct svga_context *svga)
draw_enable_line_stipple(svga->swtnl.draw, !screen->haveLineStipple);
/* always install AA point stage */
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe, bool_type);
/* Set wide line threshold above device limit (so we'll never really use it)
*/