summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-03-31 15:27:42 +1000
committerDave Airlie <airlied@redhat.com>2017-03-15 14:33:23 +1000
commit222e42e45fc1e91e707343a7e6a32c6bd725eb10 (patch)
tree3bbcfdc317074d3880f6098c5e0c3404b4d444ac /src/gallium/drivers/r600
parent0cf717821e7880d06bcd5755e5f9abe91ffae29e (diff)
r600: refactor out CB setup.
This moves the code to create CB info out into a separate function so it can be reused in images code to create RATs. Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c247
1 files changed, 143 insertions, 104 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 5cb95f85c7..4d86570ade 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -997,95 +997,63 @@ static void evergreen_get_scissor_rect(struct r600_context *rctx,
*br = S_028244_BR_X(scissor.maxx) | S_028244_BR_Y(scissor.maxy);
}
-/**
- * This function intializes the CB* register values for RATs. It is meant
- * to be used for 1D aligned buffers that do not have an associated
- * radeon_surf.
- */
-void evergreen_init_color_surface_rat(struct r600_context *rctx,
- struct r600_surface *surf)
-{
- struct pipe_resource *pipe_buffer = surf->base.texture;
- unsigned format = r600_translate_colorformat(rctx->b.chip_class,
- surf->base.format, FALSE);
- unsigned endian = r600_colorformat_endian_swap(format, FALSE);
- unsigned swap = r600_translate_colorswap(surf->base.format, FALSE);
- unsigned block_size =
- align(util_format_get_blocksize(pipe_buffer->format), 4);
- unsigned pitch_alignment =
- MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
- unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
-
- surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
-
- surf->cb_color_pitch = (pitch / 8) - 1;
-
- surf->cb_color_slice = 0;
-
- surf->cb_color_view = 0;
-
- surf->cb_color_info =
- S_028C70_ENDIAN(endian)
- | S_028C70_FORMAT(format)
- | S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
- | S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
- | S_028C70_COMP_SWAP(swap)
- | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
- * are using NUMBER_UINT */
- | S_028C70_RAT(1)
- ;
-
- surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
-
- /* For buffers, CB_COLOR0_DIM needs to be set to the number of
- * elements. */
- surf->cb_color_dim = pipe_buffer->width0;
-
- /* Set the buffer range the GPU will have access to: */
- util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
- 0, pipe_buffer->width0);
-
- surf->cb_color_fmask = surf->cb_color_base;
- surf->cb_color_fmask_slice = 0;
-}
+struct r600_tex_color_info {
+ unsigned info;
+ unsigned view;
+ unsigned dim;
+ unsigned pitch;
+ unsigned slice;
+ unsigned attrib;
+ unsigned ntype;
+ unsigned fmask;
+ unsigned fmask_slice;
+ uint64_t offset;
+ boolean export_16bpc;
+};
-void evergreen_init_color_surface(struct r600_context *rctx,
- struct r600_surface *surf)
+static void evergreen_set_color_surface_common(struct r600_context *rctx,
+ struct r600_texture *rtex,
+ unsigned level,
+ unsigned first_layer,
+ unsigned last_layer,
+ enum pipe_format pformat,
+ struct r600_tex_color_info *color)
{
struct r600_screen *rscreen = rctx->screen;
- struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
- unsigned level = surf->base.u.tex.level;
unsigned pitch, slice;
- unsigned color_info, color_attrib, color_dim = 0, color_view;
- unsigned format, swap, ntype, endian;
- uint64_t offset, base_offset;
unsigned non_disp_tiling, macro_aspect, tile_split, bankh, bankw, fmask_bankh, nbanks;
+ unsigned format, swap, ntype, endian;
const struct util_format_description *desc;
- int i;
bool blend_clamp = 0, blend_bypass = 0, do_endian_swap = FALSE;
+ int i;
+
+ color->offset = rtex->surface.level[level].offset;
+ color->view = S_028C6C_SLICE_START(first_layer) |
+ S_028C6C_SLICE_MAX(last_layer);
- offset = rtex->surface.level[level].offset;
- color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
- S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
+ color->offset += rtex->resource.gpu_address;
+ color->offset >>= 8;
+ color->dim = 0;
pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
if (slice) {
slice = slice - 1;
}
- color_info = 0;
+
+ color->info = 0;
switch (rtex->surface.level[level].mode) {
default:
case RADEON_SURF_MODE_LINEAR_ALIGNED:
- color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+ color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
non_disp_tiling = 1;
break;
case RADEON_SURF_MODE_1D:
- color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
+ color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
non_disp_tiling = rtex->non_disp_tiling;
break;
case RADEON_SURF_MODE_2D:
- color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
+ color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
non_disp_tiling = rtex->non_disp_tiling;
break;
}
@@ -1103,34 +1071,32 @@ void evergreen_init_color_surface(struct r600_context *rctx,
bankh = eg_bank_wh(bankh);
fmask_bankh = eg_bank_wh(fmask_bankh);
- /* 128 bit formats require tile type = 1 */
if (rscreen->b.chip_class == CAYMAN) {
- if (util_format_get_blocksize(surf->base.format) >= 16)
+ if (util_format_get_blocksize(pformat) >= 16)
non_disp_tiling = 1;
}
nbanks = eg_num_banks(rscreen->b.info.r600_num_banks);
- desc = util_format_description(surf->base.format);
+ desc = util_format_description(pformat);
for (i = 0; i < 4; i++) {
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
break;
}
}
-
- color_attrib = S_028C74_TILE_SPLIT(tile_split)|
- S_028C74_NUM_BANKS(nbanks) |
- S_028C74_BANK_WIDTH(bankw) |
- S_028C74_BANK_HEIGHT(bankh) |
- S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
- S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
- S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+ color->attrib = S_028C74_TILE_SPLIT(tile_split)|
+ S_028C74_NUM_BANKS(nbanks) |
+ S_028C74_BANK_WIDTH(bankw) |
+ S_028C74_BANK_HEIGHT(bankh) |
+ S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
+ S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
+ S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
if (rctx->b.chip_class == CAYMAN) {
- color_attrib |= S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
+ color->attrib |= S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
PIPE_SWIZZLE_1);
if (rtex->resource.b.b.nr_samples > 1) {
unsigned log_samples = util_logbase2(rtex->resource.b.b.nr_samples);
- color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
+ color->attrib |= S_028C74_NUM_SAMPLES(log_samples) |
S_028C74_NUM_FRAGMENTS(log_samples);
}
}
@@ -1153,11 +1119,9 @@ void evergreen_init_color_surface(struct r600_context *rctx,
if (R600_BIG_ENDIAN)
do_endian_swap = !rtex->db_compatible;
- format = r600_translate_colorformat(rctx->b.chip_class, surf->base.format,
- do_endian_swap);
+ format = r600_translate_colorformat(rctx->b.chip_class, pformat, do_endian_swap);
assert(format != ~0);
-
- swap = r600_translate_colorswap(surf->base.format, do_endian_swap);
+ swap = r600_translate_colorswap(pformat, do_endian_swap);
assert(swap != ~0);
endian = r600_colorformat_endian_swap(format, do_endian_swap);
@@ -1176,52 +1140,127 @@ void evergreen_init_color_surface(struct r600_context *rctx,
blend_bypass = 1;
}
- surf->alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
-
- color_info |= S_028C70_FORMAT(format) |
+ color->ntype = ntype;
+ color->info |= S_028C70_FORMAT(format) |
S_028C70_COMP_SWAP(swap) |
S_028C70_BLEND_CLAMP(blend_clamp) |
S_028C70_BLEND_BYPASS(blend_bypass) |
S_028C70_NUMBER_TYPE(ntype) |
S_028C70_ENDIAN(endian);
+ if (rtex->fmask.size) {
+ color->info |= S_028C70_COMPRESSION(1);
+ }
+
/* EXPORT_NORM is an optimzation that can be enabled for better
* performance in certain cases.
* EXPORT_NORM can be enabled if:
* - 11-bit or smaller UNORM/SNORM/SRGB
* - 16-bit or smaller FLOAT
*/
+ color->export_16bpc = false;
if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
((desc->channel[i].size < 12 &&
desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) ||
(desc->channel[i].size < 17 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
- color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
- surf->export_16bpc = true;
+ color->info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
+ color->export_16bpc = true;
}
+ color->pitch = S_028C64_PITCH_TILE_MAX(pitch);
+ color->slice = S_028C68_SLICE_TILE_MAX(slice);
+
if (rtex->fmask.size) {
- color_info |= S_028C70_COMPRESSION(1);
+ color->fmask = (rtex->resource.gpu_address + rtex->fmask.offset) >> 8;
+ color->fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
+ } else {
+ color->fmask = color->offset;
+ color->fmask_slice = S_028C88_TILE_MAX(slice);
}
+}
+
+/**
+ * This function intializes the CB* register values for RATs. It is meant
+ * to be used for 1D aligned buffers that do not have an associated
+ * radeon_surf.
+ */
+void evergreen_init_color_surface_rat(struct r600_context *rctx,
+ struct r600_surface *surf)
+{
+ struct pipe_resource *pipe_buffer = surf->base.texture;
+ unsigned format = r600_translate_colorformat(rctx->b.chip_class,
+ surf->base.format, FALSE);
+ unsigned endian = r600_colorformat_endian_swap(format, FALSE);
+ unsigned swap = r600_translate_colorswap(surf->base.format, FALSE);
+ unsigned block_size =
+ align(util_format_get_blocksize(pipe_buffer->format), 4);
+ unsigned pitch_alignment =
+ MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
+ unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
+
+ surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
+
+ surf->cb_color_pitch = (pitch / 8) - 1;
+
+ surf->cb_color_slice = 0;
+
+ surf->cb_color_view = 0;
+
+ surf->cb_color_info =
+ S_028C70_ENDIAN(endian)
+ | S_028C70_FORMAT(format)
+ | S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
+ | S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
+ | S_028C70_COMP_SWAP(swap)
+ | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
+ * are using NUMBER_UINT */
+ | S_028C70_RAT(1)
+ ;
+
+ surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
+
+ /* For buffers, CB_COLOR0_DIM needs to be set to the number of
+ * elements. */
+ surf->cb_color_dim = pipe_buffer->width0;
+
+ /* Set the buffer range the GPU will have access to: */
+ util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
+ 0, pipe_buffer->width0);
- base_offset = rtex->resource.gpu_address;
+ surf->cb_color_fmask = surf->cb_color_base;
+ surf->cb_color_fmask_slice = 0;
+}
+
+
+void evergreen_init_color_surface(struct r600_context *rctx,
+ struct r600_surface *surf)
+{
+ struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
+ unsigned level = surf->base.u.tex.level;
+ struct r600_tex_color_info color;
+
+ evergreen_set_color_surface_common(rctx, rtex, level,
+ surf->base.u.tex.first_layer,
+ surf->base.u.tex.last_layer,
+ surf->base.format,
+ &color);
+
+ surf->alphatest_bypass = color.ntype == V_028C70_NUMBER_UINT ||
+ color.ntype == V_028C70_NUMBER_SINT;
+ surf->export_16bpc = color.export_16bpc;
/* XXX handle enabling of CB beyond BASE8 which has different offset */
- surf->cb_color_base = (base_offset + offset) >> 8;
- surf->cb_color_dim = color_dim;
- surf->cb_color_info = color_info;
- surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch);
- surf->cb_color_slice = S_028C68_SLICE_TILE_MAX(slice);
- surf->cb_color_view = color_view;
- surf->cb_color_attrib = color_attrib;
- if (rtex->fmask.size) {
- surf->cb_color_fmask = (base_offset + rtex->fmask.offset) >> 8;
- surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
- } else {
- surf->cb_color_fmask = surf->cb_color_base;
- surf->cb_color_fmask_slice = S_028C88_TILE_MAX(slice);
- }
+ surf->cb_color_base = color.offset;
+ surf->cb_color_dim = color.dim;
+ surf->cb_color_info = color.info;
+ surf->cb_color_pitch = color.pitch;
+ surf->cb_color_slice = color.slice;
+ surf->cb_color_view = color.view;
+ surf->cb_color_attrib = color.attrib;
+ surf->cb_color_fmask = color.fmask;
+ surf->cb_color_fmask_slice = color.fmask_slice;
surf->color_initialized = true;
}