mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 22:30:12 +01:00
r600: implement EXT_window_rectangles
This is a backport of 0ca8294ece ("radeonsi:
implement EXT_window_rectangles")
This change was tested and passes the piglit tests (20/20)
on rv770, palm and cayman.
Signed-off-by: Patrick Lerda <patrick9876@free.fr>
Acked-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34295>
This commit is contained in:
parent
c1ce2dcc66
commit
6fab29d37e
8 changed files with 117 additions and 1 deletions
|
|
@ -4670,6 +4670,7 @@ void evergreen_init_state_functions(struct r600_context *rctx)
|
||||||
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
|
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
|
||||||
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
|
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
|
||||||
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
|
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
|
||||||
|
r600_add_atom(rctx, &rctx->b.window_rectangles.atom, id++);
|
||||||
for (i = 0; i < EG_NUM_HW_STAGES; i++)
|
for (i = 0; i < EG_NUM_HW_STAGES; i++)
|
||||||
r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
|
r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
|
||||||
r600_init_atom(rctx, &rctx->shader_stages.atom, id++, evergreen_emit_shader_stages, 15);
|
r600_init_atom(rctx, &rctx->shader_stages.atom, id++, evergreen_emit_shader_stages, 15);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,9 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
|
||||||
util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa_state.cso);
|
util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa_state.cso);
|
||||||
util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref.pipe_state);
|
util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref.pipe_state);
|
||||||
util_blitter_save_sample_mask(rctx->blitter, rctx->sample_mask.sample_mask, rctx->ps_iter_samples);
|
util_blitter_save_sample_mask(rctx->blitter, rctx->sample_mask.sample_mask, rctx->ps_iter_samples);
|
||||||
|
util_blitter_save_window_rectangles(rctx->blitter, rctx->b.window_rectangles.include,
|
||||||
|
rctx->b.window_rectangles.number,
|
||||||
|
rctx->b.window_rectangles.states);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op & R600_SAVE_CONST_BUF0) {
|
if (op & R600_SAVE_CONST_BUF0) {
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,7 @@ static void r600_init_screen_caps(struct r600_screen *rscreen)
|
||||||
caps->two_sided_color = false;
|
caps->two_sided_color = false;
|
||||||
caps->cull_distance = true;
|
caps->cull_distance = true;
|
||||||
|
|
||||||
|
caps->max_window_rectangles = R600_MAX_WINDOW_RECTANGLES;
|
||||||
caps->shader_buffer_offset_alignment = family >= CHIP_CEDAR ? 256 : 0;
|
caps->shader_buffer_offset_alignment = family >= CHIP_CEDAR ? 256 : 0;
|
||||||
|
|
||||||
caps->max_shader_patch_varyings = family >= CHIP_CEDAR ? 30 : 0;
|
caps->max_shader_patch_varyings = family >= CHIP_CEDAR ? 30 : 0;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "tgsi/tgsi_scan.h"
|
#include "tgsi/tgsi_scan.h"
|
||||||
|
|
||||||
#define R600_NUM_ATOMS 56
|
#define R600_NUM_ATOMS 57
|
||||||
|
|
||||||
#define R600_MAX_IMAGES 8
|
#define R600_MAX_IMAGES 8
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,16 @@ struct r600_viewports {
|
||||||
struct r600_signed_scissor as_scissor[R600_MAX_VIEWPORTS];
|
struct r600_signed_scissor as_scissor[R600_MAX_VIEWPORTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* EXT_window_rectangles */
|
||||||
|
#define R600_MAX_WINDOW_RECTANGLES 4
|
||||||
|
|
||||||
|
struct r600_window_rectangles {
|
||||||
|
unsigned number;
|
||||||
|
bool include;
|
||||||
|
struct pipe_scissor_state states[R600_MAX_WINDOW_RECTANGLES];
|
||||||
|
struct r600_atom atom;
|
||||||
|
};
|
||||||
|
|
||||||
struct r600_ring {
|
struct r600_ring {
|
||||||
struct radeon_cmdbuf cs;
|
struct radeon_cmdbuf cs;
|
||||||
void (*flush)(void *ctx, unsigned flags,
|
void (*flush)(void *ctx, unsigned flags,
|
||||||
|
|
@ -493,6 +503,7 @@ struct r600_common_context {
|
||||||
struct r600_streamout streamout;
|
struct r600_streamout streamout;
|
||||||
struct r600_scissors scissors;
|
struct r600_scissors scissors;
|
||||||
struct r600_viewports viewports;
|
struct r600_viewports viewports;
|
||||||
|
struct r600_window_rectangles window_rectangles;
|
||||||
bool scissor_enabled;
|
bool scissor_enabled;
|
||||||
bool clip_halfz;
|
bool clip_halfz;
|
||||||
bool vs_writes_viewport_index;
|
bool vs_writes_viewport_index;
|
||||||
|
|
|
||||||
|
|
@ -3104,6 +3104,7 @@ void r600_init_state_functions(struct r600_context *rctx)
|
||||||
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
|
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
|
||||||
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
|
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
|
||||||
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
|
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
|
||||||
|
r600_add_atom(rctx, &rctx->b.window_rectangles.atom, id++);
|
||||||
for (i = 0; i < R600_NUM_HW_STAGES; i++)
|
for (i = 0; i < R600_NUM_HW_STAGES; i++)
|
||||||
r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
|
r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
|
||||||
r600_init_atom(rctx, &rctx->shader_stages.atom, id++, r600_emit_shader_stages, 0);
|
r600_init_atom(rctx, &rctx->shader_stages.atom, id++, r600_emit_shader_stages, 0);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "r600_cs.h"
|
#include "r600_cs.h"
|
||||||
#include "util/u_viewport.h"
|
#include "util/u_viewport.h"
|
||||||
#include "tgsi/tgsi_scan.h"
|
#include "tgsi/tgsi_scan.h"
|
||||||
|
#include "r600d.h"
|
||||||
|
|
||||||
#define R600_R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x028C0C
|
#define R600_R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x028C0C
|
||||||
#define CM_R_028BE8_PA_CL_GB_VERT_CLIP_ADJ 0x28be8
|
#define CM_R_028BE8_PA_CL_GB_VERT_CLIP_ADJ 0x28be8
|
||||||
|
|
@ -425,14 +426,96 @@ void r600_update_vs_writes_viewport_index(struct r600_common_context *rctx,
|
||||||
rctx->set_atom_dirty(rctx, &rctx->viewports.atom, true);
|
rctx->set_atom_dirty(rctx, &rctx->viewports.atom, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void r600_emit_window_rectangles(struct r600_common_context *rctx,
|
||||||
|
struct r600_atom *atom)
|
||||||
|
{
|
||||||
|
/* There are four clipping rectangles. Their corner coordinates are inclusive.
|
||||||
|
* Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
|
||||||
|
* on whether the pixel is inside cliprects 0-3, respectively. For example,
|
||||||
|
* if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned
|
||||||
|
* the number 3 (binary 0011).
|
||||||
|
*
|
||||||
|
* If CLIPRECT_RULE & (1 << number), the pixel is rasterized.
|
||||||
|
*/
|
||||||
|
struct radeon_cmdbuf *cs = &rctx->gfx.cs;
|
||||||
|
static const unsigned outside[4] = {
|
||||||
|
/* outside rectangle 0 */
|
||||||
|
V_02820C_OUT |
|
||||||
|
V_02820C_IN_1 |
|
||||||
|
V_02820C_IN_2 |
|
||||||
|
V_02820C_IN_21 |
|
||||||
|
V_02820C_IN_3 |
|
||||||
|
V_02820C_IN_31 |
|
||||||
|
V_02820C_IN_32 |
|
||||||
|
V_02820C_IN_321,
|
||||||
|
/* outside rectangles 0, 1 */
|
||||||
|
V_02820C_OUT |
|
||||||
|
V_02820C_IN_2 |
|
||||||
|
V_02820C_IN_3 |
|
||||||
|
V_02820C_IN_32,
|
||||||
|
/* outside rectangles 0, 1, 2 */
|
||||||
|
V_02820C_OUT |
|
||||||
|
V_02820C_IN_3,
|
||||||
|
/* outside rectangles 0, 1, 2, 3 */
|
||||||
|
V_02820C_OUT,
|
||||||
|
};
|
||||||
|
const unsigned disabled = 0xffff; /* all inside and outside cases */
|
||||||
|
unsigned num_rectangles = rctx->window_rectangles.number;
|
||||||
|
struct pipe_scissor_state *rects = rctx->window_rectangles.states;
|
||||||
|
unsigned rule;
|
||||||
|
|
||||||
|
assert(num_rectangles <= R600_MAX_WINDOW_RECTANGLES);
|
||||||
|
|
||||||
|
if (num_rectangles == 0)
|
||||||
|
rule = disabled;
|
||||||
|
else if (rctx->window_rectangles.include)
|
||||||
|
rule = ~outside[num_rectangles - 1];
|
||||||
|
else
|
||||||
|
rule = outside[num_rectangles - 1];
|
||||||
|
|
||||||
|
radeon_set_context_reg_seq(cs, R_02820C_PA_SC_CLIPRECT_RULE, 1);
|
||||||
|
radeon_emit(cs, rule);
|
||||||
|
|
||||||
|
if (num_rectangles == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
radeon_set_context_reg_seq(cs, R_028210_PA_SC_CLIPRECT_0_TL,
|
||||||
|
num_rectangles * 2);
|
||||||
|
for (unsigned i = 0; i < num_rectangles; i++) {
|
||||||
|
radeon_emit(cs, S_028210_TL_X(rects[i].minx) |
|
||||||
|
S_028210_TL_Y(rects[i].miny));
|
||||||
|
radeon_emit(cs, S_028214_BR_X(rects[i].maxx) |
|
||||||
|
S_028214_BR_Y(rects[i].maxy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r600_set_window_rectangles(struct pipe_context *ctx,
|
||||||
|
bool include,
|
||||||
|
unsigned num_rectangles,
|
||||||
|
const struct pipe_scissor_state *rects)
|
||||||
|
{
|
||||||
|
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
|
||||||
|
|
||||||
|
rctx->window_rectangles.number = num_rectangles;
|
||||||
|
rctx->window_rectangles.include = include;
|
||||||
|
|
||||||
|
if (num_rectangles)
|
||||||
|
memcpy(rctx->window_rectangles.states, rects,
|
||||||
|
sizeof(*rects) * num_rectangles);
|
||||||
|
|
||||||
|
rctx->set_atom_dirty(rctx, &rctx->window_rectangles.atom, true);
|
||||||
|
}
|
||||||
|
|
||||||
void r600_init_viewport_functions(struct r600_common_context *rctx)
|
void r600_init_viewport_functions(struct r600_common_context *rctx)
|
||||||
{
|
{
|
||||||
rctx->scissors.atom.emit = r600_emit_scissors;
|
rctx->scissors.atom.emit = r600_emit_scissors;
|
||||||
rctx->viewports.atom.emit = r600_emit_viewport_states;
|
rctx->viewports.atom.emit = r600_emit_viewport_states;
|
||||||
|
rctx->window_rectangles.atom.emit = r600_emit_window_rectangles;
|
||||||
|
|
||||||
rctx->scissors.atom.num_dw = (2 + 16 * 2) + 6;
|
rctx->scissors.atom.num_dw = (2 + 16 * 2) + 6;
|
||||||
rctx->viewports.atom.num_dw = 2 + 16 * 6;
|
rctx->viewports.atom.num_dw = 2 + 16 * 6;
|
||||||
|
|
||||||
rctx->b.set_scissor_states = r600_set_scissor_states;
|
rctx->b.set_scissor_states = r600_set_scissor_states;
|
||||||
rctx->b.set_viewport_states = r600_set_viewport_states;
|
rctx->b.set_viewport_states = r600_set_viewport_states;
|
||||||
|
rctx->b.set_window_rectangles = r600_set_window_rectangles;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2849,6 +2849,22 @@
|
||||||
#define S_02820C_CLIP_RULE(x) (((unsigned)(x) & 0xFFFF) << 0)
|
#define S_02820C_CLIP_RULE(x) (((unsigned)(x) & 0xFFFF) << 0)
|
||||||
#define G_02820C_CLIP_RULE(x) (((x) >> 0) & 0xFFFF)
|
#define G_02820C_CLIP_RULE(x) (((x) >> 0) & 0xFFFF)
|
||||||
#define C_02820C_CLIP_RULE 0xFFFF0000
|
#define C_02820C_CLIP_RULE 0xFFFF0000
|
||||||
|
#define V_02820C_OUT 0x0001
|
||||||
|
#define V_02820C_IN_0 0x0002
|
||||||
|
#define V_02820C_IN_1 0x0004
|
||||||
|
#define V_02820C_IN_10 0x0008
|
||||||
|
#define V_02820C_IN_2 0x0010
|
||||||
|
#define V_02820C_IN_20 0x0020
|
||||||
|
#define V_02820C_IN_21 0x0040
|
||||||
|
#define V_02820C_IN_210 0x0080
|
||||||
|
#define V_02820C_IN_3 0x0100
|
||||||
|
#define V_02820C_IN_30 0x0200
|
||||||
|
#define V_02820C_IN_31 0x0400
|
||||||
|
#define V_02820C_IN_310 0x0800
|
||||||
|
#define V_02820C_IN_32 0x1000
|
||||||
|
#define V_02820C_IN_320 0x2000
|
||||||
|
#define V_02820C_IN_321 0x4000
|
||||||
|
#define V_02820C_IN_3210 0x8000
|
||||||
#define R_028210_PA_SC_CLIPRECT_0_TL 0x028210
|
#define R_028210_PA_SC_CLIPRECT_0_TL 0x028210
|
||||||
#define S_028210_TL_X(x) (((unsigned)(x) & 0x3FFF) << 0)
|
#define S_028210_TL_X(x) (((unsigned)(x) & 0x3FFF) << 0)
|
||||||
#define G_028210_TL_X(x) (((x) >> 0) & 0x3FFF)
|
#define G_028210_TL_X(x) (((x) >> 0) & 0x3FFF)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue