~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/etnaviv/etnaviv_emit.h

  • Committer: mmach
  • Date: 2022-09-22 19:58:36 UTC
  • Revision ID: netbit73@gmail.com-20220922195836-9nl9joew85y8d25o
2022-07-04 12:44:28

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2012-2015 Etnaviv Project
 
3
 *
 
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:
 
10
 *
 
11
 * The above copyright notice and this permission notice (including the
 
12
 * next paragraph) shall be included in all copies or substantial portions
 
13
 * of the Software.
 
14
 *
 
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.
 
22
 *
 
23
 * Authors:
 
24
 *    Wladimir J. van der Laan <laanwj@gmail.com>
 
25
 */
 
26
 
 
27
#ifndef H_ETNA_EMIT
 
28
#define H_ETNA_EMIT
 
29
 
 
30
#include "etnaviv_screen.h"
 
31
#include "etnaviv_util.h"
 
32
#include "hw/cmdstream.xml.h"
 
33
 
 
34
struct etna_context;
 
35
 
 
36
struct etna_coalesce {
 
37
   uint32_t start;
 
38
   uint32_t last_reg;
 
39
   uint32_t last_fixp;
 
40
};
 
41
 
 
42
static inline void
 
43
etna_emit_load_state(struct etna_cmd_stream *stream, const uint16_t offset,
 
44
                     const uint16_t count, const int fixp)
 
45
{
 
46
   uint32_t v;
 
47
 
 
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);
 
53
 
 
54
   etna_cmd_stream_emit(stream, v);
 
55
}
 
56
 
 
57
static inline void
 
58
etna_set_state(struct etna_cmd_stream *stream, uint32_t address, uint32_t value)
 
59
{
 
60
   etna_cmd_stream_reserve(stream, 2);
 
61
   etna_emit_load_state(stream, address >> 2, 1, 0);
 
62
   etna_cmd_stream_emit(stream, value);
 
63
}
 
64
 
 
65
static inline void
 
66
etna_set_state_reloc(struct etna_cmd_stream *stream, uint32_t address,
 
67
                     const struct etna_reloc *reloc)
 
68
{
 
69
   etna_cmd_stream_reserve(stream, 2);
 
70
   etna_emit_load_state(stream, address >> 2, 1, 0);
 
71
   etna_cmd_stream_reloc(stream, reloc);
 
72
}
 
73
 
 
74
static inline void
 
75
etna_set_state_multi(struct etna_cmd_stream *stream, uint32_t base,
 
76
                     uint32_t num, const uint32_t *values)
 
77
{
 
78
   if (num == 0)
 
79
      return;
 
80
 
 
81
   etna_cmd_stream_reserve(stream, 1 + num + 1); /* 1 extra for potential alignment */
 
82
   etna_emit_load_state(stream, base >> 2, num, 0);
 
83
 
 
84
   for (uint32_t i = 0; i < num; i++)
 
85
      etna_cmd_stream_emit(stream, values[i]);
 
86
 
 
87
   /* add potential padding */
 
88
   if ((num % 2) == 0)
 
89
      etna_cmd_stream_emit(stream, 0);
 
90
}
 
91
 
 
92
void
 
93
etna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to);
 
94
 
 
95
static inline void
 
96
etna_draw_primitives(struct etna_cmd_stream *stream, uint32_t primitive_type,
 
97
                     uint32_t start, uint32_t count)
 
98
{
 
99
   etna_cmd_stream_reserve(stream, 4);
 
100
 
 
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);
 
105
}
 
106
 
 
107
static inline void
 
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)
 
111
{
 
112
   etna_cmd_stream_reserve(stream, 5 + 1);
 
113
 
 
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);
 
120
}
 
121
 
 
122
/* important: this takes a vertex count, not a primitive count */
 
123
static inline void
 
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)
 
128
{
 
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);
 
141
}
 
142
 
 
143
static inline void
 
144
etna_coalesce_start(struct etna_cmd_stream *stream,
 
145
                    struct etna_coalesce *coalesce)
 
146
{
 
147
   coalesce->start = etna_cmd_stream_offset(stream);
 
148
   coalesce->last_reg = 0;
 
149
   coalesce->last_fixp = 0;
 
150
}
 
151
 
 
152
static inline void
 
153
etna_coalesce_end(struct etna_cmd_stream *stream,
 
154
                  struct etna_coalesce *coalesce)
 
155
{
 
156
   uint32_t end = etna_cmd_stream_offset(stream);
 
157
   uint32_t size = end - coalesce->start;
 
158
 
 
159
   if (size) {
 
160
      uint32_t offset = coalesce->start - 1;
 
161
      uint32_t value = etna_cmd_stream_get(stream, offset);
 
162
 
 
163
      value |= VIV_FE_LOAD_STATE_HEADER_COUNT(size);
 
164
      etna_cmd_stream_set(stream, offset, value);
 
165
   }
 
166
 
 
167
   /* append needed padding */
 
168
   if (end % 2 == 1)
 
169
      etna_cmd_stream_emit(stream, 0xdeadbeef);
 
170
}
 
171
 
 
172
static inline void
 
173
check_coalsence(struct etna_cmd_stream *stream, struct etna_coalesce *coalesce,
 
174
                uint32_t reg, uint32_t fixp)
 
175
{
 
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);
 
181
      }
 
182
   } else {
 
183
      etna_emit_load_state(stream, reg >> 2, 0, fixp);
 
184
      coalesce->start = etna_cmd_stream_offset(stream);
 
185
   }
 
186
 
 
187
   coalesce->last_reg = reg;
 
188
   coalesce->last_fixp = fixp;
 
189
}
 
190
 
 
191
static inline void
 
192
etna_coalsence_emit(struct etna_cmd_stream *stream,
 
193
                    struct etna_coalesce *coalesce, uint32_t reg,
 
194
                    uint32_t value)
 
195
{
 
196
   check_coalsence(stream, coalesce, reg, 0);
 
197
   etna_cmd_stream_emit(stream, value);
 
198
}
 
199
 
 
200
static inline void
 
201
etna_coalsence_emit_fixp(struct etna_cmd_stream *stream,
 
202
                         struct etna_coalesce *coalesce, uint32_t reg,
 
203
                         uint32_t value)
 
204
{
 
205
   check_coalsence(stream, coalesce, reg, 1);
 
206
   etna_cmd_stream_emit(stream, value);
 
207
}
 
208
 
 
209
static inline void
 
210
etna_coalsence_emit_reloc(struct etna_cmd_stream *stream,
 
211
                          struct etna_coalesce *coalesce, uint32_t reg,
 
212
                          const struct etna_reloc *r)
 
213
{
 
214
   if (r->bo) {
 
215
      check_coalsence(stream, coalesce, reg, 0);
 
216
      etna_cmd_stream_reloc(stream, r);
 
217
   }
 
218
}
 
219
 
 
220
void
 
221
etna_emit_state(struct etna_context *ctx);
 
222
 
 
223
#endif