2 * Copyright (c) 2012-2015 Etnaviv Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 * Wladimir J. van der Laan <laanwj@gmail.com>
27 #include "etnaviv_rs.h"
28 #include "etnaviv_screen.h"
29 #include "etnaviv_tiling.h"
30 #include "etnaviv_util.h"
32 #include "hw/common.xml.h"
33 #include "hw/state.xml.h"
34 #include "hw/state_3d.xml.h"
39 etna_compile_rs_state(struct etna_context
*ctx
, struct compiled_rs_state
*cs
,
40 const struct rs_state
*rs
)
42 memset(cs
, 0, sizeof(*cs
));
44 /* TILED and SUPERTILED layout have their strides multiplied with 4 in RS */
45 unsigned source_stride_shift
= COND(rs
->source_tiling
!= ETNA_LAYOUT_LINEAR
, 2);
46 unsigned dest_stride_shift
= COND(rs
->dest_tiling
!= ETNA_LAYOUT_LINEAR
, 2);
48 /* tiling == ETNA_LAYOUT_MULTI_TILED or ETNA_LAYOUT_MULTI_SUPERTILED? */
49 int source_multi
= COND(rs
->source_tiling
& ETNA_LAYOUT_BIT_MULTI
, 1);
50 int dest_multi
= COND(rs
->dest_tiling
& ETNA_LAYOUT_BIT_MULTI
, 1);
52 /* Vivante RS needs widths to be a multiple of 16 or bad things
53 * happen, such as scribbing over memory, or the GPU hanging,
54 * even for non-tiled formats. As this is serious, use abort().
56 if (rs
->width
& ETNA_RS_WIDTH_MASK
)
59 /* TODO could just pre-generate command buffer, would simply submit to one memcpy */
60 cs
->RS_CONFIG
= VIVS_RS_CONFIG_SOURCE_FORMAT(rs
->source_format
) |
61 COND(rs
->downsample_x
, VIVS_RS_CONFIG_DOWNSAMPLE_X
) |
62 COND(rs
->downsample_y
, VIVS_RS_CONFIG_DOWNSAMPLE_Y
) |
63 COND(rs
->source_tiling
& 1, VIVS_RS_CONFIG_SOURCE_TILED
) |
64 VIVS_RS_CONFIG_DEST_FORMAT(rs
->dest_format
) |
65 COND(rs
->dest_tiling
& 1, VIVS_RS_CONFIG_DEST_TILED
) |
66 COND(rs
->swap_rb
, VIVS_RS_CONFIG_SWAP_RB
) |
67 COND(rs
->flip
, VIVS_RS_CONFIG_FLIP
);
69 cs
->RS_SOURCE_STRIDE
= (rs
->source_stride
<< source_stride_shift
) |
70 COND(rs
->source_tiling
& 2, VIVS_RS_SOURCE_STRIDE_TILING
) |
71 COND(source_multi
, VIVS_RS_SOURCE_STRIDE_MULTI
);
73 cs
->source
[0].bo
= rs
->source
;
74 cs
->source
[0].offset
= rs
->source_offset
;
75 cs
->source
[0].flags
= ETNA_RELOC_READ
;
77 cs
->dest
[0].bo
= rs
->dest
;
78 cs
->dest
[0].offset
= rs
->dest_offset
;
79 cs
->dest
[0].flags
= ETNA_RELOC_WRITE
;
81 cs
->RS_DEST_STRIDE
= (rs
->dest_stride
<< dest_stride_shift
) |
82 COND(rs
->dest_tiling
& 2, VIVS_RS_DEST_STRIDE_TILING
) |
83 COND(dest_multi
, VIVS_RS_DEST_STRIDE_MULTI
);
85 if (ctx
->specs
.pixel_pipes
== 1) {
86 cs
->RS_WINDOW_SIZE
= VIVS_RS_WINDOW_SIZE_WIDTH(rs
->width
) |
87 VIVS_RS_WINDOW_SIZE_HEIGHT(rs
->height
);
88 } else if (ctx
->specs
.pixel_pipes
== 2) {
89 assert((rs
->height
& 7) == 0); /* GPU hangs happen if height not 8-aligned */
92 cs
->source
[1].bo
= rs
->source
;
93 cs
->source
[1].offset
= rs
->source_offset
+ rs
->source_stride
* rs
->source_padded_height
/ 2;
94 cs
->source
[1].flags
= ETNA_RELOC_READ
;
98 cs
->dest
[1].bo
= rs
->dest
;
99 cs
->dest
[1].offset
= rs
->dest_offset
+ rs
->dest_stride
* rs
->dest_padded_height
/ 2;
100 cs
->dest
[1].flags
= ETNA_RELOC_WRITE
;
103 cs
->RS_WINDOW_SIZE
= VIVS_RS_WINDOW_SIZE_WIDTH(rs
->width
) |
104 VIVS_RS_WINDOW_SIZE_HEIGHT(rs
->height
/ 2);
109 cs
->RS_PIPE_OFFSET
[0] = VIVS_RS_PIPE_OFFSET_X(0) | VIVS_RS_PIPE_OFFSET_Y(0);
110 cs
->RS_PIPE_OFFSET
[1] = VIVS_RS_PIPE_OFFSET_X(0) | VIVS_RS_PIPE_OFFSET_Y(rs
->height
/ 2);
111 cs
->RS_DITHER
[0] = rs
->dither
[0];
112 cs
->RS_DITHER
[1] = rs
->dither
[1];
113 cs
->RS_CLEAR_CONTROL
= VIVS_RS_CLEAR_CONTROL_BITS(rs
->clear_bits
) | rs
->clear_mode
;
114 cs
->RS_FILL_VALUE
[0] = rs
->clear_value
[0];
115 cs
->RS_FILL_VALUE
[1] = rs
->clear_value
[1];
116 cs
->RS_FILL_VALUE
[2] = rs
->clear_value
[2];
117 cs
->RS_FILL_VALUE
[3] = rs
->clear_value
[3];
118 cs
->RS_EXTRA_CONFIG
= VIVS_RS_EXTRA_CONFIG_AA(rs
->aa
) |
119 VIVS_RS_EXTRA_CONFIG_ENDIAN(rs
->endian_mode
);
123 etna_modify_rs_clearbits(struct compiled_rs_state
*cs
, uint32_t clear_bits
)
125 cs
->RS_CLEAR_CONTROL
&= ~VIVS_RS_CLEAR_CONTROL_BITS__MASK
;
126 cs
->RS_CLEAR_CONTROL
|= VIVS_RS_CLEAR_CONTROL_BITS(clear_bits
);