X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_clear.c;h=1e28e27586a81932a305d4a5785639f51aa75393;hb=8a723282e3f7a312ab0ca3aa9157e5b76ec182af;hp=362cef46286c7435fd7f09a1eb0f4f298c05d9bf;hpb=e599b8f384b4fc48b450ed848d93e27e876de53f;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 362cef46286..1e28e27586a 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -33,9 +33,11 @@ * Michel Dänzer */ +#include "main/errors.h" #include "main/glheader.h" #include "main/accum.h" #include "main/formats.h" +#include "main/framebuffer.h" #include "main/macros.h" #include "main/glformats.h" #include "program/prog_instruction.h" @@ -46,14 +48,15 @@ #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" #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" -#include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_simple_shaders.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); @@ -180,12 +239,14 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) const struct gl_framebuffer *fb = ctx->DrawBuffer; const GLfloat fb_width = (GLfloat) fb->Width; const GLfloat fb_height = (GLfloat) fb->Height; + + _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); + const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f; const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; - unsigned num_layers = - util_framebuffer_get_num_layers(&st->state.framebuffer); + unsigned num_layers = st->state.fb_num_layers; /* printf("%s %s%s%s %f,%f %f,%f\n", __func__, @@ -206,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 */ @@ -224,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) @@ -271,6 +325,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) cso_set_stream_outputs(cso, 0, NULL, NULL); cso_set_sample_mask(cso, ~0); cso_set_min_samples(cso, 1); + st->clear.raster.multisample = st->state.fb_num_samples > 1; cso_set_rasterizer(cso, &st->clear.raster); /* viewport state: viewport matching window dims */ @@ -313,37 +368,25 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) static inline GLboolean is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb) { - return (ctx->Scissor.EnableFlags & 1) && - (ctx->Scissor.ScissorArray[0].X > 0 || - ctx->Scissor.ScissorArray[0].Y > 0 || - (unsigned) ctx->Scissor.ScissorArray[0].Width < rb->Width || - (unsigned) ctx->Scissor.ScissorArray[0].Height < rb->Height); -} - + const struct gl_scissor_rect *scissor = &ctx->Scissor.ScissorArray[0]; -/** - * 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 (ctx->Scissor.EnableFlags & 1) && + (scissor->X > 0 || + scissor->Y > 0 || + scissor->X + scissor->Width < (int)rb->Width || + scissor->Y + scissor->Height < (int)rb->Height); } - /** - * Return if any of the color channels are masked. + * Return if window rectangles must be enabled during the clear. */ -static inline GLboolean -is_color_masked(struct gl_context *ctx, int i) +static inline bool +is_window_rectangle_enabled(struct gl_context *ctx) { - return !ctx->Color.ColorMask[i][0] || - !ctx->Color.ColorMask[i][1] || - !ctx->Color.ColorMask[i][2] || - !ctx->Color.ColorMask[i][3]; + if (ctx->DrawBuffer == ctx->WinSysDrawBuffer) + return false; + return ctx->Scissor.NumWindowRects > 0 || + ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT; } @@ -389,15 +432,16 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) GLuint i; st_flush_bitmap_cache(st); + st_invalidate_readpix_cache(st); /* This makes sure the pipe has the latest scissor, etc values */ - st_validate_state( st, ST_PIPELINE_RENDER ); + st_validate_state(st, ST_PIPELINE_CLEAR); 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); @@ -406,11 +450,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_color_masked(ctx, colormask_index)) + is_window_rectangle_enabled(ctx) || + ((colormask & surf_colormask) != surf_colormask)) quad_buffers |= PIPE_CLEAR_COLOR0 << i; else clear_buffers |= PIPE_CLEAR_COLOR0 << i; @@ -422,7 +473,8 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface && ctx->Depth.Mask) { - if (is_scissor_enabled(ctx, depthRb)) + if (is_scissor_enabled(ctx, depthRb) || + is_window_rectangle_enabled(ctx)) quad_buffers |= PIPE_CLEAR_DEPTH; else clear_buffers |= PIPE_CLEAR_DEPTH; @@ -433,6 +485,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) { if (is_scissor_enabled(ctx, stencilRb) || + is_window_rectangle_enabled(ctx) || is_stencil_masked(ctx, stencilRb)) quad_buffers |= PIPE_CLEAR_STENCIL; else @@ -453,9 +506,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. @@ -464,6 +514,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); }