gallium/radeon: add R600/Evergreen/Cayman support to common viewport code

Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Reviewed-by: Grigori Goronzy <greg@chown.ath.cx>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
Marek Olšák 2016-04-10 12:53:12 +02:00
parent 2ca5566ed7
commit 87a5b07f90
3 changed files with 50 additions and 17 deletions

View file

@ -636,6 +636,8 @@ void r600_init_screen_texture_functions(struct r600_common_screen *rscreen);
void r600_init_context_texture_functions(struct r600_common_context *rctx); void r600_init_context_texture_functions(struct r600_common_context *rctx);
/* r600_viewport.c */ /* r600_viewport.c */
void evergreen_apply_scissor_bug_workaround(struct r600_common_context *rctx,
struct pipe_scissor_state *scissor);
void r600_set_scissor_enable(struct r600_common_context *rctx, bool enable); void r600_set_scissor_enable(struct r600_common_context *rctx, bool enable);
void r600_update_vs_writes_viewport_index(struct r600_common_context *rctx, void r600_update_vs_writes_viewport_index(struct r600_common_context *rctx,
struct tgsi_shader_info *info); struct tgsi_shader_info *info);

View file

@ -24,6 +24,8 @@
#include "r600_cs.h" #include "r600_cs.h"
#include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_scan.h"
#define GET_MAX_SCISSOR(rctx) (rctx->chip_class >= EVERGREEN ? 16384 : 8192)
static void r600_set_scissor_states(struct pipe_context *ctx, static void r600_set_scissor_states(struct pipe_context *ctx,
unsigned start_slot, unsigned start_slot,
unsigned num_scissors, unsigned num_scissors,
@ -42,7 +44,8 @@ static void r600_set_scissor_states(struct pipe_context *ctx,
rctx->set_atom_dirty(rctx, &rctx->scissors.atom, true); rctx->set_atom_dirty(rctx, &rctx->scissors.atom, true);
} }
static void r600_get_scissor_from_viewport(const struct pipe_viewport_state *vp, static void r600_get_scissor_from_viewport(struct r600_common_context *rctx,
const struct pipe_viewport_state *vp,
struct r600_signed_scissor *scissor) struct r600_signed_scissor *scissor)
{ {
int tmp; int tmp;
@ -57,7 +60,7 @@ static void r600_get_scissor_from_viewport(const struct pipe_viewport_state *vp,
if (scissor->minx == -1 && scissor->miny == -1 && if (scissor->minx == -1 && scissor->miny == -1 &&
scissor->maxx == 1 && scissor->maxy == 1) { scissor->maxx == 1 && scissor->maxy == 1) {
scissor->minx = scissor->miny = 0; scissor->minx = scissor->miny = 0;
scissor->maxx = scissor->maxy = 16384; scissor->maxx = scissor->maxy = GET_MAX_SCISSOR(rctx);
} }
/* Handle inverted viewports. */ /* Handle inverted viewports. */
@ -73,13 +76,15 @@ static void r600_get_scissor_from_viewport(const struct pipe_viewport_state *vp,
} }
} }
static void r600_clamp_scissor(struct pipe_scissor_state *out, static void r600_clamp_scissor(struct r600_common_context *rctx,
struct pipe_scissor_state *out,
struct r600_signed_scissor *scissor) struct r600_signed_scissor *scissor)
{ {
out->minx = CLAMP(scissor->minx, 0, 16384); unsigned max_scissor = GET_MAX_SCISSOR(rctx);
out->miny = CLAMP(scissor->miny, 0, 16384); out->minx = CLAMP(scissor->minx, 0, max_scissor);
out->maxx = CLAMP(scissor->maxx, 0, 16384); out->miny = CLAMP(scissor->miny, 0, max_scissor);
out->maxy = CLAMP(scissor->maxy, 0, 16384); out->maxx = CLAMP(scissor->maxx, 0, max_scissor);
out->maxy = CLAMP(scissor->maxy, 0, max_scissor);
} }
static void r600_clip_scissor(struct pipe_scissor_state *out, static void r600_clip_scissor(struct pipe_scissor_state *out,
@ -100,7 +105,23 @@ static void r600_scissor_make_union(struct r600_signed_scissor *out,
out->maxy = MAX2(out->maxy, in->maxy); out->maxy = MAX2(out->maxy, in->maxy);
} }
static void r600_emit_one_scissor(struct radeon_winsys_cs *cs, void evergreen_apply_scissor_bug_workaround(struct r600_common_context *rctx,
struct pipe_scissor_state *scissor)
{
if (rctx->chip_class == EVERGREEN || rctx->chip_class == CAYMAN) {
if (scissor->maxx == 0)
scissor->minx = 1;
if (scissor->maxy == 0)
scissor->miny = 1;
if (rctx->chip_class == CAYMAN &&
scissor->maxx == 1 && scissor->maxy == 1)
scissor->maxx = 2;
}
}
static void r600_emit_one_scissor(struct r600_common_context *rctx,
struct radeon_winsys_cs *cs,
struct r600_signed_scissor *vp_scissor, struct r600_signed_scissor *vp_scissor,
struct pipe_scissor_state *scissor) struct pipe_scissor_state *scissor)
{ {
@ -109,11 +130,13 @@ static void r600_emit_one_scissor(struct radeon_winsys_cs *cs,
/* Since the guard band disables clipping, we have to clip per-pixel /* Since the guard band disables clipping, we have to clip per-pixel
* using a scissor. * using a scissor.
*/ */
r600_clamp_scissor(&final, vp_scissor); r600_clamp_scissor(rctx, &final, vp_scissor);
if (scissor) if (scissor)
r600_clip_scissor(&final, scissor); r600_clip_scissor(&final, scissor);
evergreen_apply_scissor_bug_workaround(rctx, &final);
radeon_emit(cs, S_028250_TL_X(final.minx) | radeon_emit(cs, S_028250_TL_X(final.minx) |
S_028250_TL_Y(final.miny) | S_028250_TL_Y(final.miny) |
S_028250_WINDOW_OFFSET_DISABLE(1)); S_028250_WINDOW_OFFSET_DISABLE(1));
@ -122,7 +145,7 @@ static void r600_emit_one_scissor(struct radeon_winsys_cs *cs,
} }
/* the range is [-MAX, MAX] */ /* the range is [-MAX, MAX] */
#define R600_MAX_VIEWPORT_RANGE 32768 #define GET_MAX_VIEWPORT_RANGE(rctx) (rctx->chip_class >= EVERGREEN ? 32768 : 16384)
static void r600_emit_guardband(struct r600_common_context *rctx, static void r600_emit_guardband(struct r600_common_context *rctx,
struct r600_signed_scissor *vp_as_scissor) struct r600_signed_scissor *vp_as_scissor)
@ -152,7 +175,7 @@ static void r600_emit_guardband(struct r600_common_context *rctx,
* *
* Use a limit one pixel smaller to allow for some precision error. * Use a limit one pixel smaller to allow for some precision error.
*/ */
max_range = R600_MAX_VIEWPORT_RANGE - 1; max_range = GET_MAX_VIEWPORT_RANGE(rctx) - 1;
left = (-max_range - vp.translate[0]) / vp.scale[0]; left = (-max_range - vp.translate[0]) / vp.scale[0];
right = ( max_range - vp.translate[0]) / vp.scale[0]; right = ( max_range - vp.translate[0]) / vp.scale[0];
top = (-max_range - vp.translate[1]) / vp.scale[1]; top = (-max_range - vp.translate[1]) / vp.scale[1];
@ -164,7 +187,11 @@ static void r600_emit_guardband(struct r600_common_context *rctx,
guardband_y = MIN2(-top, bottom); guardband_y = MIN2(-top, bottom);
/* If any of the GB registers is updated, all of them must be updated. */ /* If any of the GB registers is updated, all of them must be updated. */
radeon_set_context_reg_seq(cs, CM_R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4); if (rctx->chip_class >= CAYMAN)
radeon_set_context_reg_seq(cs, CM_R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4);
else
radeon_set_context_reg_seq(cs, R600_R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 4);
radeon_emit(cs, fui(guardband_y)); /* R_028BE8_PA_CL_GB_VERT_CLIP_ADJ */ radeon_emit(cs, fui(guardband_y)); /* R_028BE8_PA_CL_GB_VERT_CLIP_ADJ */
radeon_emit(cs, fui(1.0)); /* R_028BEC_PA_CL_GB_VERT_DISC_ADJ */ radeon_emit(cs, fui(1.0)); /* R_028BEC_PA_CL_GB_VERT_DISC_ADJ */
radeon_emit(cs, fui(guardband_x)); /* R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ */ radeon_emit(cs, fui(guardband_x)); /* R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ */
@ -188,7 +215,7 @@ static void r600_emit_scissors(struct r600_common_context *rctx, struct r600_ato
return; return;
radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2); radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2);
r600_emit_one_scissor(cs, vp, scissor_enabled ? &states[0] : NULL); r600_emit_one_scissor(rctx, cs, vp, scissor_enabled ? &states[0] : NULL);
r600_emit_guardband(rctx, vp); r600_emit_guardband(rctx, vp);
rctx->scissors.dirty_mask &= ~1; /* clear one bit */ rctx->scissors.dirty_mask &= ~1; /* clear one bit */
return; return;
@ -208,8 +235,8 @@ static void r600_emit_scissors(struct r600_common_context *rctx, struct r600_ato
radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL +
start * 4 * 2, count * 2); start * 4 * 2, count * 2);
for (i = start; i < start+count; i++) { for (i = start; i < start+count; i++) {
r600_emit_one_scissor(cs, &rctx->viewports.as_scissor[i], r600_emit_one_scissor(rctx, cs, &rctx->viewports.as_scissor[i],
scissor_enabled ? &states[i] : NULL); scissor_enabled ? &states[i] : NULL);
} }
} }
r600_emit_guardband(rctx, &max_vp_scissor); r600_emit_guardband(rctx, &max_vp_scissor);
@ -228,8 +255,8 @@ static void r600_set_viewport_states(struct pipe_context *ctx,
unsigned index = start_slot + i; unsigned index = start_slot + i;
rctx->viewports.states[index] = state[i]; rctx->viewports.states[index] = state[i];
r600_get_scissor_from_viewport(&state[i], r600_get_scissor_from_viewport(rctx, &state[i],
&rctx->viewports.as_scissor[index]); &rctx->viewports.as_scissor[index]);
} }
rctx->viewports.dirty_mask |= ((1 << num_viewports) - 1) << start_slot; rctx->viewports.dirty_mask |= ((1 << num_viewports) - 1) << start_slot;
@ -315,6 +342,9 @@ 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_viewports; rctx->viewports.atom.emit = r600_emit_viewports;
rctx->scissors.atom.num_dw = (2 + 16 * 2) + 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;
} }

View file

@ -220,6 +220,7 @@
/*CIK+*/ /*CIK+*/
#define R_0300FC_CP_STRMOUT_CNTL 0x0300FC #define R_0300FC_CP_STRMOUT_CNTL 0x0300FC
#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
#define R_02843C_PA_CL_VPORT_XSCALE 0x02843C #define R_02843C_PA_CL_VPORT_XSCALE 0x02843C