diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 3986d6469e3..44acf011699 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -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); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 56fff878885..b1b66f6532f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -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; diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c index 0ebc1ef0b69..96cd395d44d 100644 --- a/src/gallium/auxiliary/nir/nir_draw_helpers.c +++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c @@ -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); } } } diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.h b/src/gallium/auxiliary/nir/nir_draw_helpers.h index 114fc8d89b4..ef6ffd79b20 100644 --- a/src/gallium/auxiliary/nir/nir_draw_helpers.h +++ b/src/gallium/auxiliary/nir/nir_draw_helpers.h @@ -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 } diff --git a/src/gallium/drivers/i915/ci/i915-g33-fails.txt b/src/gallium/drivers/i915/ci/i915-g33-fails.txt index caa0ea55084..e450f4d3782 100644 --- a/src/gallium/drivers/i915/ci/i915-g33-fails.txt +++ b/src/gallium/drivers/i915/ci/i915-g33-fails.txt @@ -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 diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index e283a42f279..dfaa111e725 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -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; diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 8d9c2ed01ed..343aecc61cc 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -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: diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index ee668330e72..4d98f904c77 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -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); diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index da2d5f46121..a16d2272201 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -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) */