gallium: add support for programmable sample locations

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Brian Paul <brianp@vmware.com> (v2)
Reviewed-by: Marek Olšák <marek.olsak@amd.com> (v2)
This commit is contained in:
Rhys Perry
2018-06-14 19:56:28 -06:00
committed by Brian Paul
parent 67f40dadaa
commit 51a221e378
24 changed files with 120 additions and 2 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
^^^^^^^^^

View File

@@ -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:

View File

@@ -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. */

View File

@@ -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:

View File

@@ -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:

View File

@@ -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 */

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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. */

View File

@@ -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:

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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. */

View File

@@ -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. */

View File

@@ -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;

View File

@@ -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,
@@ -484,6 +511,16 @@ struct pipe_context {
const void *clear_value,
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.
*
@@ -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

View File

@@ -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,
};
/**

View File

@@ -131,6 +131,17 @@ struct pipe_screen {
enum pipe_compute_cap param,
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

View File

@@ -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