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:
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
^^^^^^^^^
|
||||
|
@@ -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:
|
||||
|
@@ -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. */
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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 */
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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. */
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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. */
|
||||
|
@@ -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. */
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user