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>
30 #include "etnaviv_screen.h"
31 #include "etnaviv_util.h"
32 #include "hw/cmdstream.xml.h"
36 struct etna_coalesce
{
43 etna_emit_load_state(struct etna_cmd_stream
*stream
, const uint16_t offset
,
44 const uint16_t count
, const int fixp
)
48 v
= VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE
|
49 COND(fixp
, VIV_FE_LOAD_STATE_HEADER_FIXP
) |
50 VIV_FE_LOAD_STATE_HEADER_OFFSET(offset
) |
51 (VIV_FE_LOAD_STATE_HEADER_COUNT(count
) &
52 VIV_FE_LOAD_STATE_HEADER_COUNT__MASK
);
54 etna_cmd_stream_emit(stream
, v
);
58 etna_set_state(struct etna_cmd_stream
*stream
, uint32_t address
, uint32_t value
)
60 etna_cmd_stream_reserve(stream
, 2);
61 etna_emit_load_state(stream
, address
>> 2, 1, 0);
62 etna_cmd_stream_emit(stream
, value
);
66 etna_set_state_reloc(struct etna_cmd_stream
*stream
, uint32_t address
,
67 const struct etna_reloc
*reloc
)
69 etna_cmd_stream_reserve(stream
, 2);
70 etna_emit_load_state(stream
, address
>> 2, 1, 0);
71 etna_cmd_stream_reloc(stream
, reloc
);
75 etna_set_state_multi(struct etna_cmd_stream
*stream
, uint32_t base
,
76 uint32_t num
, const uint32_t *values
)
81 etna_cmd_stream_reserve(stream
, 1 + num
+ 1); /* 1 extra for potential alignment */
82 etna_emit_load_state(stream
, base
>> 2, num
, 0);
84 for (uint32_t i
= 0; i
< num
; i
++)
85 etna_cmd_stream_emit(stream
, values
[i
]);
87 /* add potential padding */
89 etna_cmd_stream_emit(stream
, 0);
93 etna_stall(struct etna_cmd_stream
*stream
, uint32_t from
, uint32_t to
);
96 etna_draw_primitives(struct etna_cmd_stream
*stream
, uint32_t primitive_type
,
97 uint32_t start
, uint32_t count
)
99 etna_cmd_stream_reserve(stream
, 4);
101 etna_cmd_stream_emit(stream
, VIV_FE_DRAW_PRIMITIVES_HEADER_OP_DRAW_PRIMITIVES
);
102 etna_cmd_stream_emit(stream
, primitive_type
);
103 etna_cmd_stream_emit(stream
, start
);
104 etna_cmd_stream_emit(stream
, count
);
108 etna_draw_indexed_primitives(struct etna_cmd_stream
*stream
,
109 uint32_t primitive_type
, uint32_t start
,
110 uint32_t count
, uint32_t offset
)
112 etna_cmd_stream_reserve(stream
, 5 + 1);
114 etna_cmd_stream_emit(stream
, VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER_OP_DRAW_INDEXED_PRIMITIVES
);
115 etna_cmd_stream_emit(stream
, primitive_type
);
116 etna_cmd_stream_emit(stream
, start
);
117 etna_cmd_stream_emit(stream
, count
);
118 etna_cmd_stream_emit(stream
, offset
);
119 etna_cmd_stream_emit(stream
, 0);
122 /* important: this takes a vertex count, not a primitive count */
124 etna_draw_instanced(struct etna_cmd_stream
*stream
,
125 uint32_t indexed
, uint32_t primitive_type
,
126 uint32_t instance_count
,
127 uint32_t vertex_count
, uint32_t offset
)
129 etna_cmd_stream_reserve(stream
, 3 + 1);
130 etna_cmd_stream_emit(stream
,
131 VIV_FE_DRAW_INSTANCED_HEADER_OP_DRAW_INSTANCED
|
132 COND(indexed
, VIV_FE_DRAW_INSTANCED_HEADER_INDEXED
) |
133 VIV_FE_DRAW_INSTANCED_HEADER_TYPE(primitive_type
) |
134 VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO(instance_count
& 0xffff));
135 etna_cmd_stream_emit(stream
,
136 VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI(instance_count
>> 16) |
137 VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT(vertex_count
));
138 etna_cmd_stream_emit(stream
,
139 VIV_FE_DRAW_INSTANCED_START_INDEX(offset
));
140 etna_cmd_stream_emit(stream
, 0);
144 etna_coalesce_start(struct etna_cmd_stream
*stream
,
145 struct etna_coalesce
*coalesce
)
147 coalesce
->start
= etna_cmd_stream_offset(stream
);
148 coalesce
->last_reg
= 0;
149 coalesce
->last_fixp
= 0;
153 etna_coalesce_end(struct etna_cmd_stream
*stream
,
154 struct etna_coalesce
*coalesce
)
156 uint32_t end
= etna_cmd_stream_offset(stream
);
157 uint32_t size
= end
- coalesce
->start
;
160 uint32_t offset
= coalesce
->start
- 1;
161 uint32_t value
= etna_cmd_stream_get(stream
, offset
);
163 value
|= VIV_FE_LOAD_STATE_HEADER_COUNT(size
);
164 etna_cmd_stream_set(stream
, offset
, value
);
167 /* append needed padding */
169 etna_cmd_stream_emit(stream
, 0xdeadbeef);
173 check_coalsence(struct etna_cmd_stream
*stream
, struct etna_coalesce
*coalesce
,
174 uint32_t reg
, uint32_t fixp
)
176 if (coalesce
->last_reg
!= 0) {
177 if (((coalesce
->last_reg
+ 4) != reg
) || (coalesce
->last_fixp
!= fixp
)) {
178 etna_coalesce_end(stream
, coalesce
);
179 etna_emit_load_state(stream
, reg
>> 2, 0, fixp
);
180 coalesce
->start
= etna_cmd_stream_offset(stream
);
183 etna_emit_load_state(stream
, reg
>> 2, 0, fixp
);
184 coalesce
->start
= etna_cmd_stream_offset(stream
);
187 coalesce
->last_reg
= reg
;
188 coalesce
->last_fixp
= fixp
;
192 etna_coalsence_emit(struct etna_cmd_stream
*stream
,
193 struct etna_coalesce
*coalesce
, uint32_t reg
,
196 check_coalsence(stream
, coalesce
, reg
, 0);
197 etna_cmd_stream_emit(stream
, value
);
201 etna_coalsence_emit_fixp(struct etna_cmd_stream
*stream
,
202 struct etna_coalesce
*coalesce
, uint32_t reg
,
205 check_coalsence(stream
, coalesce
, reg
, 1);
206 etna_cmd_stream_emit(stream
, value
);
210 etna_coalsence_emit_reloc(struct etna_cmd_stream
*stream
,
211 struct etna_coalesce
*coalesce
, uint32_t reg
,
212 const struct etna_reloc
*r
)
215 check_coalsence(stream
, coalesce
, reg
, 0);
216 etna_cmd_stream_reloc(stream
, r
);
221 etna_emit_state(struct etna_context
*ctx
);