X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_clear.c;h=06fb9798c687b678ad999a3e79de40cac354dd6f;hb=0c74e354d10b3a7640f682a43ca0984bc93fa3ef;hp=cda9c71729cfc594201c4c43f1f05ce4cfffd707;hpb=585c5cf8a514783d9ed31dba3aa432797dd5f0e8;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index cda9c71729c..06fb9798c68 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -33,6 +33,7 @@ * Michel Dänzer */ +#include "main/errors.h" #include "main/glheader.h" #include "main/accum.h" #include "main/formats.h" @@ -47,7 +48,9 @@ #include "st_cb_fbo.h" #include "st_draw.h" #include "st_format.h" +#include "st_nir.h" #include "st_program.h" +#include "st_util.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" @@ -70,7 +73,8 @@ st_init_clear(struct st_context *st) st->clear.raster.half_pixel_center = 1; st->clear.raster.bottom_edge_rule = 1; - st->clear.raster.depth_clip = 1; + st->clear.raster.depth_clip_near = 1; + st->clear.raster.depth_clip_far = 1; } @@ -105,34 +109,83 @@ st_destroy_clear(struct st_context *st) static inline void set_fragment_shader(struct st_context *st) { - if (!st->clear.fs) - st->clear.fs = - util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC, - TGSI_INTERPOLATE_CONSTANT, - TRUE); + struct pipe_screen *pscreen = st->pipe->screen; + bool use_nir = PIPE_SHADER_IR_NIR == + pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, + PIPE_SHADER_CAP_PREFERRED_IR); + + if (!st->clear.fs) { + if (use_nir) { + unsigned inputs[] = { VARYING_SLOT_VAR0 }; + unsigned outputs[] = { FRAG_RESULT_COLOR }; + unsigned interpolation[] = { INTERP_MODE_FLAT }; + st->clear.fs = st_nir_make_passthrough_shader(st, "clear FS", + MESA_SHADER_FRAGMENT, + 1, inputs, outputs, + interpolation, 0); + } else { + st->clear.fs = + util_make_fragment_passthrough_shader(st->pipe, + TGSI_SEMANTIC_GENERIC, + TGSI_INTERPOLATE_CONSTANT, + TRUE); + } + } cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); } +static void * +make_nir_clear_vertex_shader(struct st_context *st, bool layered) +{ + const char *shader_name = layered ? "layered clear VS" : "clear VS"; + unsigned inputs[] = { + VERT_ATTRIB_POS, + VERT_ATTRIB_GENERIC0, + SYSTEM_VALUE_INSTANCE_ID, + }; + unsigned outputs[] = { + VARYING_SLOT_POS, + VARYING_SLOT_VAR0, + VARYING_SLOT_LAYER + }; + + return st_nir_make_passthrough_shader(st, shader_name, MESA_SHADER_VERTEX, + layered ? 3 : 2, inputs, outputs, + NULL, (1 << 2)); +} + + /** * Helper function to set the vertex shader. */ static inline void set_vertex_shader(struct st_context *st) { + struct pipe_screen *pscreen = st->pipe->screen; + bool use_nir = PIPE_SHADER_IR_NIR == + pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, + PIPE_SHADER_CAP_PREFERRED_IR); + /* vertex shader - still required to provide the linkage between * fragment shader input semantics and vertex_element/buffers. */ if (!st->clear.vs) { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2, - semantic_names, - semantic_indexes, - FALSE); + if (use_nir) { + st->clear.vs = make_nir_clear_vertex_shader(st, false); + } else { + const enum tgsi_semantic semantic_names[] = { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC + }; + const uint semantic_indexes[] = { 0, 0 }; + st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2, + semantic_names, + semantic_indexes, + FALSE); + } } cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); @@ -144,6 +197,10 @@ static void set_vertex_shader_layered(struct st_context *st) { struct pipe_context *pipe = st->pipe; + struct pipe_screen *pscreen = pipe->screen; + bool use_nir = PIPE_SHADER_IR_NIR == + pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, + PIPE_SHADER_CAP_PREFERRED_IR); if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) { assert(!"Got layered clear, but VS instancing is unsupported"); @@ -155,7 +212,9 @@ set_vertex_shader_layered(struct st_context *st) bool vs_layer = pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT); if (vs_layer) { - st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe); + st->clear.vs_layered = + use_nir ? make_nir_clear_vertex_shader(st, true) + : util_make_layered_clear_vertex_shader(pipe); } else { st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe); st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe); @@ -208,7 +267,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) CSO_BIT_STREAM_OUTPUTS | CSO_BIT_VERTEX_ELEMENTS | CSO_BIT_AUX_VERTEX_BUFFER_SLOT | - CSO_BIT_PAUSE_QUERIES | + (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) | CSO_BITS_ALL_SHADERS)); /* blend state: RGBA masking */ @@ -226,14 +285,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i))) continue; - if (ctx->Color.ColorMask[i][0]) - blend.rt[i].colormask |= PIPE_MASK_R; - if (ctx->Color.ColorMask[i][1]) - blend.rt[i].colormask |= PIPE_MASK_G; - if (ctx->Color.ColorMask[i][2]) - blend.rt[i].colormask |= PIPE_MASK_B; - if (ctx->Color.ColorMask[i][3]) - blend.rt[i].colormask |= PIPE_MASK_A; + blend.rt[i].colormask = GET_COLORMASK(ctx->Color.ColorMask, i); } if (ctx->Color.DitherFlag) @@ -337,32 +389,6 @@ is_window_rectangle_enabled(struct gl_context *ctx) } -/** - * Return if all of the color channels are masked. - */ -static inline GLboolean -is_color_disabled(struct gl_context *ctx, int i) -{ - return !ctx->Color.ColorMask[i][0] && - !ctx->Color.ColorMask[i][1] && - !ctx->Color.ColorMask[i][2] && - !ctx->Color.ColorMask[i][3]; -} - - -/** - * Return if any of the color channels are masked. - */ -static inline GLboolean -is_color_masked(struct gl_context *ctx, int i) -{ - return !ctx->Color.ColorMask[i][0] || - !ctx->Color.ColorMask[i][1] || - !ctx->Color.ColorMask[i][2] || - !ctx->Color.ColorMask[i][3]; -} - - /** * Return if all of the stencil bits are masked. */ @@ -412,9 +438,9 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (mask & BUFFER_BITS_COLOR) { for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + gl_buffer_index b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - if (b >= 0 && mask & (1 << b)) { + if (b != BUFFER_NONE && mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); @@ -423,12 +449,18 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (!strb || !strb->surface) continue; - if (is_color_disabled(ctx, colormask_index)) + unsigned colormask = + GET_COLORMASK(ctx->Color.ColorMask, colormask_index); + + if (!colormask) continue; + unsigned surf_colormask = + util_format_colormask(util_format_description(strb->surface->format)); + if (is_scissor_enabled(ctx, rb) || is_window_rectangle_enabled(ctx) || - is_color_masked(ctx, colormask_index)) + ((colormask & surf_colormask) != surf_colormask)) quad_buffers |= PIPE_CLEAR_COLOR0 << i; else clear_buffers |= PIPE_CLEAR_COLOR0 << i; @@ -473,9 +505,6 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) * use pipe->clear. We want to always use pipe->clear for the other * renderbuffers, because it's likely to be faster. */ - if (quad_buffers) { - clear_with_quad(ctx, quad_buffers); - } if (clear_buffers) { /* We can't translate the clear color to the colorbuffer format, * because different colorbuffers may have different formats. @@ -484,6 +513,9 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) (union pipe_color_union*)&ctx->Color.ClearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } + if (quad_buffers) { + clear_with_quad(ctx, quad_buffers); + } if (mask & BUFFER_BIT_ACCUM) _mesa_clear_accum_buffer(ctx); }