image/svg+xml
Brteve's API for EveApps
Version 0.0.1
The reference document for common folder of EveApps project.
 
Loading...
Searching...
No Matches
EVE_MediaFifo.c
Go to the documentation of this file.
1
32#include "EVE_MediaFifo.h"
33#include "EVE_Platform.h"
34
35#ifdef EVE_SUPPORT_MEDIAFIFO
36
46{
47 bool res;
48
49 if (!EVE_Hal_supportMediaFifo(phost))
50 {
51 eve_assert_ex(false, "EVE_MediaFifo_set is not available on the current graphics platform\n");
52 return false;
53 }
54
55 if (phost->MediaFifoAddress != address || phost->MediaFifoSize != size)
56 {
57 EVE_Cmd_startFunc(phost);
59 EVE_Cmd_wr32(phost, address);
60 EVE_Cmd_wr32(phost, size);
61 EVE_Cmd_endFunc(phost);
62
63 /* Must flush for fifo pointers to be ready. */
64 res = EVE_Cmd_waitFlush(phost);
65 }
66 else
67 {
68 res = true;
69 }
70
71 if (res)
72 {
75 phost->MediaFifoAddress = address;
76 phost->MediaFifoSize = size;
77 }
78 else
79 {
80 phost->MediaFifoAddress = 0;
81 phost->MediaFifoSize = 0;
82 }
83
84 return res;
85}
86
88{
89 phost->MediaFifoAddress = 0;
90 phost->MediaFifoSize = 0;
91}
92
103
114
122{
123 if (!phost->MediaFifoSize)
124 return 0;
125
128#if 1
129 return rp > wp
130 ? (rp - wp - 4)
131 : (rp + phost->MediaFifoSize - wp - 4);
132#else
133 int32_t diff = wp - rp;
134 if (diff < 0)
135 diff += phost->MediaFifoSize;
136 eve_assert(diff >= 0 && diff < phost->MediaFifoSize);
137 return phost->MediaFifoSize - diff - 4;
138#endif
139}
140
151bool EVE_MediaFifo_wrMem(EVE_HalContext *phost, const uint8_t *buffer, uint32_t size, uint32_t *transfered)
152{
153 if (!EVE_Hal_supportMediaFifo(phost))
154 {
155 eve_assert_ex(false, "EVE_MediaFifo_wrMem is not available on the current graphics platform\n");
156 return false;
157 }
158
159 if (!phost->MediaFifoSize)
160 {
161 eve_printf_debug("EVE Media FIFO has not been set, cannot write\n");
162 return false;
163 }
164
165#if 1
166 /* Two strategies.
167 - Wait for entire space and write the entire buffer.
168 - Wait for half the fifo to be available, and write in parts. */
169
170 /* If the size is within the media fifo size, write the entire buffer at once */
171 if (size <= phost->MediaFifoSize - 4)
172 {
173 uint32_t wp;
174 int32_t overflow;
175
176 if (!EVE_MediaFifo_waitSpace(phost, size, transfered))
177 return false;
178
180 overflow = (int32_t)(wp + size) - (int32_t)(phost->MediaFifoSize);
181 if (overflow > 0)
182 {
183 eve_assert(phost->MediaFifoAddress + wp + size - overflow <= RAM_G_SIZE);
184 eve_assert(phost->MediaFifoAddress + overflow <= RAM_G_SIZE);
185 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, buffer, size - overflow);
186 EVE_Hal_wrMem(phost, phost->MediaFifoAddress, &buffer[size - overflow], overflow);
187 }
188 else
189 {
190 eve_assert(phost->MediaFifoAddress + wp + size <= RAM_G_SIZE);
191 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, buffer, size);
192 }
193 wp += size;
194 if (wp >= phost->MediaFifoSize)
195 wp -= phost->MediaFifoSize;
196 eve_assert(wp < phost->MediaFifoSize);
198 if (transfered)
199 *transfered = size;
200 return true;
201 }
202 else
203 {
204 /* Otherwise, write in parts. */
205 uint32_t halfSize = ((phost->MediaFifoSize >> 3) << 2) - 4;
206 uint32_t remaining = size;
207 uint32_t done = 0;
208 uint32_t wp;
209
211 while (remaining)
212 {
213 uint32_t transfer = min(halfSize, remaining);
214 int32_t overflow;
215 if (!EVE_MediaFifo_waitSpace(phost, transfer, transfered))
216 return false;
217
218 overflow = (int32_t)(wp + transfer) - (int32_t)(phost->MediaFifoSize);
219 if (overflow > 0)
220 {
221 eve_assert(phost->MediaFifoAddress + wp + transfer - overflow <= RAM_G_SIZE);
222 eve_assert(phost->MediaFifoAddress + overflow <= RAM_G_SIZE);
223 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, &buffer[done], transfer - overflow);
224 EVE_Hal_wrMem(phost, phost->MediaFifoAddress, &buffer[done + transfer - overflow], overflow);
225 }
226 else
227 {
228 eve_assert(phost->MediaFifoAddress + wp + transfer <= RAM_G_SIZE);
229 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, &buffer[done], transfer);
230 }
231 wp += transfer;
232 done += transfer;
233 remaining -= transfer;
234 if (wp >= phost->MediaFifoSize)
235 wp -= phost->MediaFifoSize;
236 eve_assert(wp < phost->MediaFifoSize);
238
239 if (transfered)
240 {
241 *transfered = done;
242 if (EVE_Cmd_rp(phost) == EVE_Cmd_wp(phost))
243 return true; /* Early exit, finished processing. */
244 }
245 }
246
247 return true;
248 }
249#else
250 eve_scope()
251 {
252 uint32_t halfSize = ((phost->MediaFifoSize >> 3) << 2) - 4;
253 uint32_t remaining = size;
254 uint32_t done = 0;
255 uint32_t wp;
256
257 /* Write to media FIFO as soon as space is available */
259 while (remaining)
260 {
261 uint32_t transfer = min(
262 EVE_MediaFifo_waitSpace(phost, 4),
263 min(halfSize, remaining));
264 if (!transfer)
265 return false; // !phost->CmdFault;
266 int32_t overflow = (int32_t)(wp + transfer) - (int32_t)(phost->MediaFifoSize);
267 if (overflow > 0)
268 {
269 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, &buffer[done], transfer - overflow);
270 EVE_Hal_wrMem(phost, phost->MediaFifoAddress, &buffer[done + transfer - overflow], overflow);
271 }
272 else
273 {
274 EVE_Hal_wrMem(phost, phost->MediaFifoAddress + wp, &buffer[done], transfer);
275 }
276 wp += transfer;
277 done += transfer;
278 remaining -= transfer;
279 if (wp >= phost->MediaFifoSize)
280 wp -= phost->MediaFifoSize;
281 eve_assert(wp < phost->MediaFifoSize);
283
284 if (transfered)
285 {
286 *transfered = done;
287 if (EVE_Cmd_rp(phost) == EVE_Cmd_wp(phost))
288 return true; /* Early exit, finished processing. */
289 }
290 }
291
292 return true;
293 }
294#endif
295}
296
297#if defined(_DEBUG)
299#endif
300
301static bool checkWait(EVE_HalContext *phost, uint32_t rpOrSpace)
302{
303 if (EVE_CMD_FAULT(rpOrSpace))
304 {
305 char err[128];
306 (void)err;
307 /* Coprocessor fault */
308 phost->CmdWaiting = false;
309 eve_printf_debug("Coprocessor fault in processing media FIFO\n");
310#if defined(_DEBUG)
311 debugBackupRamG(phost);
312 if (EVE_CHIPID >= EVE_BT815)
313 {
314 EVE_Hal_rdMem(phost, (uint8_t *)err, RAM_ERR_REPORT, 128);
315 eve_printf_debug("%s\n", err);
316 EVE_Hal_displayMessage(phost, err, 128);
317 }
318 else
319 {
320 EVE_Hal_displayMessage(phost, "Coprocessor fault in processing media FIFO ", sizeof("Coprocessor fault in processing media FIFO "));
321 }
322#endif
323 /* eve_debug_break(); */
324 return false;
325 }
326
327 if (phost->Status == EVE_STATUS_ERROR)
328 {
329 phost->CmdWaiting = false;
330 eve_printf_debug("Host error\n");
331 return false;
332 }
333
334 return true;
335}
336
337static bool handleWait(EVE_HalContext *phost, uint16_t rpOrSpace)
338{
339 /* Check for coprocessor fault */
340 if (!checkWait(phost, rpOrSpace))
341 return false;
342
343 /* Process any idling */
344 EVE_Hal_idle(phost);
345
346 /* Process user idling */
347 if (phost->CbCmdWait
348 && !phost->CbCmdWait(phost))
349 {
350 /* Wait aborted */
351 phost->CmdWaiting = false;
352 eve_printf_debug("Wait for media FIFO aborted\n");
353 return false;
354 }
355 return true;
356}
357
365bool EVE_MediaFifo_waitFlush(EVE_HalContext *phost, bool orCmdFlush)
366{
367 return EVE_MediaFifo_waitSpace(phost, phost->MediaFifoSize - 4, orCmdFlush);
368}
369
379{
380 uint32_t space;
381
382 if (!EVE_Hal_supportMediaFifo(phost))
383 {
384 eve_assert_ex(false, "EVE_MediaFifo_waitSpace is not available on the current graphics platform\n");
385 return 0;
386 }
387
388 if (!phost->MediaFifoSize)
389 {
390 eve_printf_debug("EVE Media FIFO has not been set, cannot wait for space\n");
391 return 0;
392 }
393
394 if (size > (phost->MediaFifoSize - 4))
395 {
396 eve_printf_debug("Requested free space exceeds media FIFO\n");
397 return 0;
398 }
399
400 eve_assert(!phost->CmdWaiting);
401 phost->CmdWaiting = true;
402
403#if 1
404 space = EVE_MediaFifo_space(phost);
405 if (!checkWait(phost, space))
406 return 0;
407#endif
408
409 do
410 {
411 space = EVE_MediaFifo_space(phost);
412 if (!handleWait(phost, (uint16_t)space))
413 return 0;
414 phost->CmdWaiting = false;
415 uint32_t cmdSpace = EVE_Cmd_waitSpace(phost, 0);
416 if (!cmdSpace)
417 return 0; /* Check for coprocessor error */
418 if (orCmdFlush && cmdSpace == (EVE_CMD_FIFO_SIZE - 4))
419 return 0; /* Processed */
420 phost->CmdWaiting = true;
421 } while (space < size);
422
423 phost->CmdWaiting = false;
424 return space;
425}
426
427#endif
428
429/* end of file */
EVE_HAL_EXPORT uint32_t EVE_Cmd_waitSpace(EVE_HalContext *phost, uint32_t size)
Definition EVE_Cmd.c:580
EVE_HAL_EXPORT void EVE_Cmd_startFunc(EVE_HalContext *phost)
Begin writing a function, keeps the transfer open.
Definition EVE_Cmd.c:262
EVE_HAL_EXPORT uint16_t EVE_Cmd_rp(EVE_HalContext *phost)
Read from Coprocessor.
Definition EVE_Cmd.c:64
EVE_HAL_EXPORT void EVE_Cmd_endFunc(EVE_HalContext *phost)
End writing a function, closes the transfer.
Definition EVE_Cmd.c:274
EVE_HAL_EXPORT uint16_t EVE_Cmd_wp(EVE_HalContext *phost)
Write to Coprocessor.
Definition EVE_Cmd.c:80
EVE_HAL_EXPORT bool EVE_Cmd_wr32(EVE_HalContext *phost, uint32_t value)
Write 4 bytes to Coprocessor's command fifo.
Definition EVE_Cmd.c:394
#define EVE_BT815
Definition EVE_Config.h:66
#define EVE_CHIPID
#define RAM_ERR_REPORT
Definition EVE_GpuDefs.h:79
#define EVE_CMD_FIFO_SIZE
Definition EVE_GpuDefs.h:58
#define REG_MEDIAFIFO_READ
#define EVE_CMD_FAULT(rp)
Definition EVE_GpuDefs.h:63
#define RAM_G_SIZE
Definition EVE_GpuDefs.h:98
#define CMD_MEDIAFIFO
#define REG_MEDIAFIFO_WRITE
EVE_HAL_EXPORT uint32_t EVE_Hal_rd32(EVE_HalContext *phost, uint32_t addr)
Read 4 bytes from Coprocessor's memory.
Definition EVE_Hal.c:189
EVE_HAL_EXPORT void EVE_Hal_rdMem(EVE_HalContext *phost, uint8_t *result, uint32_t addr, uint32_t size)
Read a block data from Coprocessor's memory.
Definition EVE_Hal.c:206
void EVE_Hal_displayMessage(EVE_HalContext *phost, const char *str, uint16_t size)
Display a fullscreen debug message using TEXT8X8. Uses the back of RAM_G.
Definition EVE_Hal.c:486
EVE_HAL_EXPORT void EVE_Hal_idle(EVE_HalContext *phost)
Idle handler for Eve_Hal framework.
Definition EVE_Hal.c:136
EVE_HAL_EXPORT void EVE_Hal_wr32(EVE_HalContext *phost, uint32_t addr, uint32_t v)
Write 4 bytes to Coprocessor's memory.
Definition EVE_Hal.c:248
EVE_HAL_EXPORT void EVE_Hal_wrMem(EVE_HalContext *phost, uint32_t addr, const uint8_t *buffer, uint32_t size)
Write a buffer to Coprocessor's memory.
Definition EVE_Hal.c:263
@ EVE_STATUS_ERROR
Definition EVE_HalDefs.h:61
static bool EVE_Hal_supportMediaFifo(EVE_HalContext *phost)
unsigned short uint16_t
int int32_t
unsigned int uint32_t
unsigned char uint8_t
void EVE_MediaFifo_close(EVE_HalContext *phost)
static bool checkWait(EVE_HalContext *phost, uint32_t rpOrSpace)
bool EVE_MediaFifo_waitFlush(EVE_HalContext *phost, bool orCmdFlush)
Wait for the media FIFO to fully empty.
uint32_t EVE_MediaFifo_wp(EVE_HalContext *phost)
Get the current write pointer.
bool EVE_MediaFifo_wrMem(EVE_HalContext *phost, const uint8_t *buffer, uint32_t size, uint32_t *transfered)
Write a buffer to the media FIFO. Waits if there is not enough space in the media FIFO.
uint32_t EVE_MediaFifo_waitSpace(EVE_HalContext *phost, uint32_t size, bool orCmdFlush)
Wait for the media FIFO to have at least the requested amount of free space.
uint32_t EVE_MediaFifo_space(EVE_HalContext *phost)
Get the currently available space.
void debugBackupRamG(EVE_HalContext *phost)
Backup the last 128 bytes of RAM_G, which may be used for an error message.
Definition EVE_Util.c:1722
static bool handleWait(EVE_HalContext *phost, uint16_t rpOrSpace)
bool EVE_MediaFifo_set(EVE_HalContext *phost, uint32_t address, uint32_t size)
Set the media FIFO.
uint32_t EVE_MediaFifo_rp(EVE_HalContext *phost)
Get the current read pointer.
EVE's mediafifo controller.
Platform selector.
#define eve_assert(cond)
#define eve_printf_debug(fmt,...)
#define eve_assert_ex(cond, ex)
static ft_uint32_t ft_uint8_t * buffer
Definition FT_Gpu_Hal.h:139
void EVE_Cmd_waitFlush(EVE_HalContext *host)
Definition Gpu_Hal.cpp:775
uint32_t MediaFifoAddress
uint32_t MediaFifoSize
EVE_Callback CbCmdWait
EVE_STATUS_T Status