From: Rhys Perry Date: Fri, 15 Jun 2018 01:56:28 +0000 (-0600) Subject: st/mesa: add support for ARB_sample_locations X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9f217facbde04dd005b3f6b53bc97480b856d246;p=mesa.git st/mesa: add support for ARB_sample_locations Signed-off-by: Rhys Perry Reviewed-by: Brian Paul (v2) Reviewed-by: Marek Olšák (v2) --- diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index 2567ad30df1..96e128d38cf 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -86,7 +86,7 @@ enum { ST_NEW_CS_SAMPLERS) #define ST_NEW_FRAMEBUFFER (ST_NEW_FB_STATE | \ - ST_NEW_SAMPLE_MASK | \ + ST_NEW_SAMPLE_STATE | \ ST_NEW_SAMPLE_SHADING) #define ST_NEW_VERTEX_PROGRAM(st, p) (p->affected_states | \ diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h index 5391d4710c1..e1aebc91e78 100644 --- a/src/mesa/state_tracker/st_atom_list.h +++ b/src/mesa/state_tracker/st_atom_list.h @@ -34,7 +34,7 @@ ST_STATE(ST_NEW_FS_IMAGES, st_bind_fs_images) ST_STATE(ST_NEW_FB_STATE, st_update_framebuffer_state) /* depends on update_*_texture and bind_*_images */ ST_STATE(ST_NEW_BLEND, st_update_blend) /* depends on update_framebuffer_state */ ST_STATE(ST_NEW_RASTERIZER, st_update_rasterizer) /* depends on update_framebuffer_state */ -ST_STATE(ST_NEW_SAMPLE_MASK, st_update_sample_mask) /* depends on update_framebuffer_state */ +ST_STATE(ST_NEW_SAMPLE_STATE, st_update_sample_state) /* depends on update_framebuffer_state */ ST_STATE(ST_NEW_SAMPLE_SHADING, st_update_sample_shading) ST_STATE(ST_NEW_SCISSOR, st_update_scissor) /* depends on update_framebuffer_state */ ST_STATE(ST_NEW_VIEWPORT, st_update_viewport) /* depends on update_framebuffer_state */ diff --git a/src/mesa/state_tracker/st_atom_msaa.c b/src/mesa/state_tracker/st_atom_msaa.c index 556c7c5889e..c6affec5525 100644 --- a/src/mesa/state_tracker/st_atom_msaa.c +++ b/src/mesa/state_tracker/st_atom_msaa.c @@ -33,13 +33,84 @@ #include "st_program.h" #include "cso_cache/cso_context.h" +#include "util/u_framebuffer.h" #include "main/framebuffer.h" -/* Update the sample mask for MSAA. +/** + * Update the sample locations + */ +static void +update_sample_locations(struct st_context *st) +{ + struct gl_framebuffer *fb = st->ctx->DrawBuffer; + + if (!st->ctx->Extensions.ARB_sample_locations) + return; + + if (fb->ProgrammableSampleLocations) { + unsigned grid_width, grid_height, size, pixel, sample_index; + unsigned samples = st->state.fb_num_samples; + bool sample_location_pixel_grid = fb->SampleLocationPixelGrid; + uint8_t locations[ + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32]; + + st->pipe->screen->get_sample_pixel_grid( + st->pipe->screen, samples, &grid_width, &grid_height); + size = grid_width * grid_height * samples; + + /** + * when a dimension is greater than MAX_SAMPLE_LOCATION_GRID_SIZE, + * st->ctx->Driver.GetSamplePixelGrid() returns 1 for both dimensions. + */ + if (grid_width > MAX_SAMPLE_LOCATION_GRID_SIZE || + grid_height > MAX_SAMPLE_LOCATION_GRID_SIZE) + sample_location_pixel_grid = false; + + for (pixel = 0; pixel < grid_width * grid_height; pixel++) { + for (sample_index = 0; sample_index < samples; sample_index++) { + int table_index = sample_index; + float x = 0.5f, y = 0.5f; + uint8_t loc; + if (sample_location_pixel_grid) + table_index = pixel * samples + sample_index; + if (fb->SampleLocationTable) { + x = fb->SampleLocationTable[table_index*2]; + y = fb->SampleLocationTable[table_index*2+1]; + } + if (st->state.fb_orientation == Y_0_BOTTOM) + y = 1.0 - y; + + loc = roundf(CLAMP(x * 16.0f, 0.0f, 15.0f)); + loc |= (int)roundf(CLAMP(y * 16.0f, 0.0f, 15.0f)) << 4; + locations[pixel * samples + sample_index] = loc; + } + } + + util_sample_locations_flip_y( + st->pipe->screen, st->state.fb_height, samples, locations); + + if (!st->state.enable_sample_locations || + st->state.sample_locations_samples != samples || + memcmp(locations, st->state.sample_locations, size) != 0) { + st->pipe->set_sample_locations( st->pipe, size, locations); + + st->state.sample_locations_samples = samples; + memcpy(st->state.sample_locations, locations, size); + } + } else if (st->state.enable_sample_locations) { + st->pipe->set_sample_locations(st->pipe, 0, NULL); + } + + st->state.enable_sample_locations = fb->ProgrammableSampleLocations; +} + + +/* Update the sample mask and locations for MSAA. */ void -st_update_sample_mask(struct st_context *st) +st_update_sample_state(struct st_context *st) { unsigned sample_mask = 0xffffffff; unsigned sample_count = st->state.fb_num_samples; @@ -64,6 +135,8 @@ st_update_sample_mask(struct st_context *st) } cso_set_sample_mask(st->cso_context, sample_mask); + + update_sample_locations(st); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 5eeec08655d..b851db64886 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -855,6 +855,19 @@ st_UnmapRenderbuffer(struct gl_context *ctx, } +/** + * Called via ctx->Driver.EvaluateDepthValues. + */ +static void +st_EvaluateDepthValues(struct gl_context *ctx) +{ + struct st_context *st = st_context(ctx); + + st_validate_state(st, ST_PIPELINE_UPDATE_FRAMEBUFFER); + + st->pipe->evaluate_depth_buffer(st->pipe); +} + void st_init_fbo_functions(struct dd_function_table *functions) @@ -871,4 +884,5 @@ st_init_fbo_functions(struct dd_function_table *functions) functions->MapRenderbuffer = st_MapRenderbuffer; functions->UnmapRenderbuffer = st_UnmapRenderbuffer; + functions->EvaluateDepthValues = st_EvaluateDepthValues; } diff --git a/src/mesa/state_tracker/st_cb_msaa.c b/src/mesa/state_tracker/st_cb_msaa.c index 7f1b4fde91d..6c5dc1fd43e 100644 --- a/src/mesa/state_tracker/st_cb_msaa.c +++ b/src/mesa/state_tracker/st_cb_msaa.c @@ -56,8 +56,35 @@ st_GetSamplePosition(struct gl_context *ctx, } +static void +st_GetProgrammableSampleCaps(struct gl_context *ctx, const struct gl_framebuffer *fb, + GLuint *outBits, GLuint *outWidth, GLuint *outHeight) +{ + struct st_context *st = st_context(ctx); + struct pipe_screen *screen = st->pipe->screen; + + st_validate_state(st, ST_PIPELINE_UPDATE_FRAMEBUFFER); + + *outBits = 4; + *outWidth = 1; + *outHeight = 1; + + if (ctx->Extensions.ARB_sample_locations) + screen->get_sample_pixel_grid(screen, st->state.fb_num_samples, + outWidth, outHeight); + + /* We could handle this better in some circumstances, + * but it's not really an issue */ + if (*outWidth > MAX_SAMPLE_LOCATION_GRID_SIZE || + *outHeight > MAX_SAMPLE_LOCATION_GRID_SIZE) { + *outWidth = 1; + *outHeight = 1; + } +} + void st_init_msaa_functions(struct dd_function_table *functions) { functions->GetSamplePosition = st_GetSamplePosition; + functions->GetProgrammableSampleCaps = st_GetProgrammableSampleCaps; } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 50c8b2e6549..6c1be76afc6 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -172,7 +172,7 @@ st_invalidate_buffers(struct st_context *st) st->dirty |= ST_NEW_BLEND | ST_NEW_DSA | ST_NEW_FB_STATE | - ST_NEW_SAMPLE_MASK | + ST_NEW_SAMPLE_STATE | ST_NEW_SAMPLE_SHADING | ST_NEW_FS_STATE | ST_NEW_POLY_STIPPLE | @@ -323,9 +323,10 @@ st_init_driver_flags(struct st_context *st) f->NewLogicOp = ST_NEW_BLEND; f->NewStencil = ST_NEW_DSA; f->NewMultisampleEnable = ST_NEW_BLEND | ST_NEW_RASTERIZER | - ST_NEW_SAMPLE_MASK | ST_NEW_SAMPLE_SHADING; + ST_NEW_SAMPLE_STATE | ST_NEW_SAMPLE_SHADING; f->NewSampleAlphaToXEnable = ST_NEW_BLEND; - f->NewSampleMask = ST_NEW_SAMPLE_MASK; + f->NewSampleMask = ST_NEW_SAMPLE_STATE; + f->NewSampleLocations = ST_NEW_SAMPLE_STATE; f->NewSampleShading = ST_NEW_SAMPLE_SHADING; /* This depends on what the gallium driver wants. */ diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 9f5bfba3fd9..a4d52b40ae4 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -178,6 +178,12 @@ struct st_context GLuint poly_stipple[32]; /**< In OpenGL's bottom-to-top order */ GLuint fb_orientation; + + bool enable_sample_locations; + unsigned sample_locations_samples; + uint8_t sample_locations[ + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32]; } state; uint64_t dirty; /**< dirty states */ diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 467d9b07596..c540cee3974 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -646,6 +646,7 @@ void st_init_extensions(struct pipe_screen *screen, { o(ARB_query_buffer_object), PIPE_CAP_QUERY_BUFFER_OBJECT }, { o(ARB_robust_buffer_access_behavior), PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR }, { o(ARB_sample_shading), PIPE_CAP_SAMPLE_SHADING }, + { o(ARB_sample_locations), PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS }, { o(ARB_seamless_cube_map), PIPE_CAP_SEAMLESS_CUBE_MAP }, { o(ARB_shader_ballot), PIPE_CAP_TGSI_BALLOT }, { o(ARB_shader_clock), PIPE_CAP_TGSI_CLOCK },