diff options
24 files changed, 120 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c index c2948a5cfb3..5bafddc726f 100644 --- a/src/gallium/auxiliary/util/u_framebuffer.c +++ b/src/gallium/auxiliary/util/u_framebuffer.c @@ -240,3 +240,33 @@ util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb) return 1; } + + +/** + * Flip the sample location state along the Y axis. + */ +void +util_sample_locations_flip_y(struct pipe_screen *screen, unsigned fb_height, + unsigned samples, uint8_t *locations) +{ + unsigned row, i, shift, grid_width, grid_height; + uint8_t new_locations[ + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * + PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32]; + + screen->get_sample_pixel_grid(screen, samples, &grid_width, &grid_height); + + shift = fb_height % grid_height; + + for (row = 0; row < grid_height; row++) { + unsigned row_size = grid_width * samples; + for (i = 0; i < row_size; i++) { + unsigned dest_row = grid_height - row - 1; + /* this relies on unsigned integer wraparound behaviour */ + dest_row = (dest_row - shift) % grid_height; + new_locations[dest_row * row_size + i] = locations[row * row_size + i]; + } + } + + memcpy(locations, new_locations, grid_width * grid_height * samples); +} diff --git a/src/gallium/auxiliary/util/u_framebuffer.h b/src/gallium/auxiliary/util/u_framebuffer.h index c73942c9c14..877e6e393f7 100644 --- a/src/gallium/auxiliary/util/u_framebuffer.h +++ b/src/gallium/auxiliary/util/u_framebuffer.h @@ -64,6 +64,11 @@ extern unsigned util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb); +extern void +util_sample_locations_flip_y(struct pipe_screen *screen, unsigned fb_height, + unsigned samples, uint8_t *locations); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index e8e80dcbc39..20d0df79312 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -68,6 +68,9 @@ objects. They all follow simple, one-method binding calls, e.g. that this takes effect even if multisampling is not explicitly enabled if the frambuffer surface(s) are multisampled. Also, this mask is AND-ed with the optional fragment shader sample mask output (when emitted). +* ``set_sample_locations`` sets the sample locations used for rasterization. + ```get_sample_position``` still returns the default locations. When NULL, + the default locations are used. * ``set_min_samples`` sets the minimum number of samples that must be run. * ``set_clip_state`` * ``set_polygon_stipple`` @@ -270,6 +273,17 @@ format. multi-byte element value starting at offset bytes from resource start, going for size bytes. It is guaranteed that size % clear_value_size == 0. +Evaluating Depth Buffers +^^^^^^^^^^^^^^^^^^^^^^^^ + +``evaluate_depth_buffer`` is a hint to decompress the current depth buffer +assuming the current sample locations to avoid problems that could arise when +using programmable sample locations. + +If a depth buffer is rendered with different sample location state than +what is current at the time of reading the depth buffer, the values may differ +because depth buffer compression can depend the sample locations. + Uploading ^^^^^^^^^ diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 0f18b7a94b9..a41c421ec47 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -438,6 +438,9 @@ PIPE_CONSERVATIVE_RASTER_PRE_SNAP mode is supported for points and lines. works with conservative rasterization. * ``PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS``: The maximum subpixel precision bias in bits during conservative rasterization. +* ``PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS``: True is the driver supports + programmable sample location through ```get_sample_pixel_grid``` and + ```set_sample_locations```. .. _pipe_capf: diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index e031807117c..36b86e5f36d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -281,6 +281,7 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: case PIPE_CAP_PACKED_UNIFORMS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index a414cb6d60e..93f3214c3c2 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -347,6 +347,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_CONTEXT_PRIORITY_MASK: diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index b08d2283e7e..d917048e2b9 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -333,6 +333,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_FENCE_SIGNAL: case PIPE_CAP_CONSTBUF0_FLAGS: case PIPE_CAP_PACKED_UNIFORMS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_MAX_VIEWPORTS: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index f12ad09298d..28dbd9908f9 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -370,6 +370,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index a77f70e6bb4..470625ba542 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -236,6 +236,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 2495a545fde..bdb2a8e31c7 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -289,6 +289,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index f679cbdba3e..8e9ede0736a 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -319,6 +319,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSTBUF0_FLAGS: case PIPE_CAP_PACKED_UNIFORMS: case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 459349e821c..793b0ba8d89 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -258,6 +258,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; /* SWTCL-only features. */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index ff7306998bb..12960ed5373 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -428,6 +428,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_DOUBLES: diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index 154fabebdcc..de05e8e7e6f 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -257,6 +257,7 @@ static int si_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_FENCE_SIGNAL: diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index f9c916d9382..8fbcbc8bac2 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -322,6 +322,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: return 4; diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 2744f3100eb..9e3e3e26a3c 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -468,6 +468,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_FENCE_SIGNAL: case PIPE_CAP_CONSTBUF0_FLAGS: case PIPE_CAP_PACKED_UNIFORMS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; } diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp index 091d322d38c..65fa1bc50e6 100644 --- a/src/gallium/drivers/swr/swr_screen.cpp +++ b/src/gallium/drivers/swr/swr_screen.cpp @@ -355,6 +355,7 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 80b8156a73e..cd84e61f277 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -269,6 +269,7 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: case PIPE_CAP_PACKED_UNIFORMS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; /* Geometry shader output, unsupported. */ diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index 6415d95746b..286263bf001 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -298,6 +298,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: case PIPE_CAP_PACKED_UNIFORMS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index f21526a60bd..fa02907392c 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -293,6 +293,7 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES: case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE: case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS: + case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: return 0; case PIPE_CAP_VENDOR_ID: return 0x1af4; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index c3dc5edf57d..7cf037f1abd 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -279,8 +279,35 @@ struct pipe_context { void (*set_framebuffer_state)( struct pipe_context *, const struct pipe_framebuffer_state * ); + /** + * Set the sample locations used during rasterization. When NULL or sized + * zero, the default locations are used. + * + * Note that get_sample_position() still returns the default locations. + * + * The samples are accessed with + * locations[(pixel_y*grid_w+pixel_x)*ms+i], + * where: + * ms = the sample count + * grid_w = the pixel grid width for the sample count + * grid_w = the pixel grid height for the sample count + * pixel_x = the window x coordinate modulo grid_w + * pixel_y = the window y coordinate modulo grid_w + * i = the sample index + * This gives a result with the x coordinate as the low 4 bits and the y + * coordinate as the high 4 bits. For each coordinate 0 is the left or top + * edge of the pixel's rectangle and 16 (not 15) is the right or bottom edge. + * + * Out of bounds accesses are return undefined values. + * + * The pixel grid is used to vary sample locations across pixels and its + * size can be queried with get_sample_pixel_grid(). + */ + void (*set_sample_locations)( struct pipe_context *, + size_t size, const uint8_t *locations ); + void (*set_polygon_stipple)( struct pipe_context *, - const struct pipe_poly_stipple * ); + const struct pipe_poly_stipple * ); void (*set_scissor_states)( struct pipe_context *, unsigned start_slot, @@ -485,6 +512,16 @@ struct pipe_context { int clear_value_size); /** + * If a depth buffer is rendered with different sample location state than + * what is current at the time of reading, the values may differ because + * depth buffer compression can depend the sample locations. + * + * This function is a hint to decompress the current depth buffer to avoid + * such problems. + */ + void (*evaluate_depth_buffer)(struct pipe_context *pipe); + + /** * Flush draw commands. * * This guarantees that the new fence (if any) will finish in finite time, @@ -720,7 +757,7 @@ struct pipe_context { /*@}*/ /** - * Get sample position for an individual sample point. + * Get the default sample position for an individual sample point. * * \param sample_count - total number of samples * \param sample_index - sample to get the position values for diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 6cc73a31bfc..43db9f8fbaa 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -813,6 +813,7 @@ enum pipe_cap PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES, PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS, PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE, + PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS, }; /** diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 8fd81a4e9a9..0439060b606 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -132,6 +132,17 @@ struct pipe_screen { void *ret); /** + * Get the sample pixel grid's size. This function requires + * PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS to be callable. + * + * \param sample_count - total number of samples + * \param out_width - the width of the pixel grid + * \param out_height - the height of the pixel grid + */ + void (*get_sample_pixel_grid)(struct pipe_screen *, unsigned sample_count, + unsigned *out_width, unsigned *out_height); + + /** * Query a timestamp in nanoseconds. The returned value should match * PIPE_QUERY_TIMESTAMP. This function returns immediately and doesn't * wait for rendering to complete (which cannot be achieved with queries). diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index db9fa1a8e9f..809aa087ce0 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -74,6 +74,7 @@ extern "C" { #define PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT 8 #define PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 2 #define PIPE_MAX_WINDOW_RECTANGLES 8 +#define PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE 4 #define PIPE_MAX_HW_ATOMIC_BUFFERS 32 |