| 9120e874 Andy McCall |
1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
#include "vera_bandwidth.h" |
| 18 |
#include "support/harness.h" |
| 19 |
|
| 20 |
#include <stdio.h> |
| 21 |
#include <string.h> |
| 22 |
|
| 23 |
|
| 24 |
#define BPP1 0 |
| 25 |
#define BPP2 1 |
| 26 |
#define BPP4 2 |
| 27 |
#define BPP8 3 |
| 28 |
|
| 29 |
static vera_bw_layer_t |
| 30 |
tile_layer(uint8_t depth, uint8_t tile_width, bool scrolled) |
| 31 |
{ |
| 32 |
vera_bw_layer_t l; |
| 33 |
memset(&l, 0, sizeof l); |
| 34 |
l.enabled = true; |
| 35 |
l.bitmap_mode = false; |
| 36 |
l.color_depth = depth; |
| 37 |
l.tile_width = tile_width; |
| 38 |
l.scrolled = scrolled; |
| 39 |
return l; |
| 40 |
} |
| 41 |
|
| 42 |
static vera_bw_layer_t |
| 43 |
bitmap_layer(uint8_t depth, uint8_t tile_width) |
| 44 |
{ |
| 45 |
vera_bw_layer_t l; |
| 46 |
memset(&l, 0, sizeof l); |
| 47 |
l.enabled = true; |
| 48 |
l.bitmap_mode = true; |
| 49 |
l.color_depth = depth; |
| 50 |
l.tile_width = tile_width; |
| 51 |
return l; |
| 52 |
} |
| 53 |
|
| 54 |
static uint16_t |
| 55 |
tile_fetches(uint8_t depth, uint8_t tile_width, bool scrolled) |
| 56 |
{ |
| 57 |
const vera_bw_layer_t l = tile_layer(depth, tile_width, scrolled); |
| 58 |
return vera_bandwidth_layer_line_fetches(&l); |
| 59 |
} |
| 60 |
|
| 61 |
static uint16_t |
| 62 |
bitmap_fetches(uint8_t depth, uint8_t tile_width) |
| 63 |
{ |
| 64 |
const vera_bw_layer_t l = bitmap_layer(depth, tile_width); |
| 65 |
return vera_bandwidth_layer_line_fetches(&l); |
| 66 |
} |
| 67 |
|
| 68 |
static void |
| 69 |
begin(void) |
| 70 |
{ |
| 71 |
vera_bandwidth_set_enabled(false); |
| 72 |
vera_bandwidth_configure(525); |
| 73 |
vera_bandwidth_set_enabled(true); |
| 74 |
vera_bandwidth_reset(); |
| 75 |
} |
| 76 |
|
| 77 |
int |
| 78 |
main(void) |
| 79 |
{ |
| 80 |
|
| 81 |
{ |
| 82 |
check_eq(VERA_BW_LINE_CLOCKS, 800, |
| 83 |
"a scanline is 800 clocks: video_vga.v:27-31, 640+16+96+48"); |
| 84 |
check_eq(VERA_BW_BYTES_PER_ACCESS, 4, |
| 85 |
"VRAM is 32 bits wide, so an access is four bytes: main_ram.v:7-10"); |
| 86 |
check_eq(VERA_BW_ACCESS_CLOCKS, 2, |
| 87 |
"an access costs strobe plus ack: layer_renderer.v:250-271"); |
| 88 |
check_eq(VERA_BW_LAYER_PIXELS, 640, |
| 89 |
"the layer renderer always fills 640 pixels: layer_renderer.v:488"); |
| 90 |
} |
| 91 |
|
| 92 |
|
| 93 |
{ |
| 94 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP1, 0), 8, |
| 95 |
"1bpp 8px tile packs 8 pixels per word"); |
| 96 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP1, 1), 16, |
| 97 |
"1bpp 16px tile packs 16"); |
| 98 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP2, 0), 8, |
| 99 |
"2bpp 8px tile packs 8"); |
| 100 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP2, 1), 16, |
| 101 |
"2bpp 16px tile packs 16"); |
| 102 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP4, 0), 8, |
| 103 |
"4bpp tile packs 8 regardless of tile width"); |
| 104 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP4, 1), 8, |
| 105 |
"4bpp 16px tile still packs 8"); |
| 106 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP8, 0), 4, |
| 107 |
"8bpp tile packs 4"); |
| 108 |
check_eq(vera_bandwidth_pixels_per_word(false, BPP8, 1), 4, |
| 109 |
"8bpp 16px tile still packs 4"); |
| 110 |
|
| 111 |
check_eq(vera_bandwidth_pixels_per_word(true, BPP1, 0), 32, |
| 112 |
"1bpp bitmap packs 32 pixels per word -- a mode that only " |
| 113 |
"exists from v47.0.2 (layer_renderer.v:48)"); |
| 114 |
check_eq(vera_bandwidth_pixels_per_word(true, BPP2, 0), 16, |
| 115 |
"2bpp bitmap packs 16"); |
| 116 |
check_eq(vera_bandwidth_pixels_per_word(true, BPP4, 0), 8, |
| 117 |
"4bpp bitmap packs 8"); |
| 118 |
check_eq(vera_bandwidth_pixels_per_word(true, BPP8, 0), 4, |
| 119 |
"8bpp bitmap packs 4"); |
| 120 |
} |
| 121 |
|
| 122 |
|
| 123 |
{ |
| 124 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP1, 0), 1, "1bpp 8px tile row is one word"); |
| 125 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP1, 1), 1, "1bpp 16px tile row is one word"); |
| 126 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP2, 0), 1, "2bpp 8px tile row is one word"); |
| 127 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP2, 1), 1, "2bpp 16px tile row is one word"); |
| 128 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP4, 0), 1, "4bpp 8px tile row is one word"); |
| 129 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP4, 1), 2, "4bpp 16px tile row is two"); |
| 130 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP8, 0), 2, "8bpp 8px tile row is two"); |
| 131 |
check_eq(vera_bandwidth_words_per_tile_line(false, BPP8, 1), 4, "8bpp 16px tile row is four"); |
| 132 |
} |
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
{ |
| 139 |
check_eq(tile_fetches(BPP1, 0, false), 40 + 80, |
| 140 |
"1bpp 8px tiles: 40 map + 80 data = 120 fetches a line"); |
| 141 |
check_eq(tile_fetches(BPP2, 0, false), 40 + 80, |
| 142 |
"2bpp 8px tiles cost the same as 1bpp: both are one word a tile"); |
| 143 |
check_eq(tile_fetches(BPP4, 0, false), 40 + 80, |
| 144 |
"4bpp 8px tiles too"); |
| 145 |
check_eq(tile_fetches(BPP8, 0, false), 40 + 160, |
| 146 |
"8bpp 8px tiles need two words a tile: 200"); |
| 147 |
|
| 148 |
check_eq(tile_fetches(BPP1, 1, false), 20 + 40, |
| 149 |
"1bpp 16px tiles halve the tile count: 60"); |
| 150 |
check_eq(tile_fetches(BPP2, 1, false), 20 + 40, "2bpp 16px tiles: 60"); |
| 151 |
check_eq(tile_fetches(BPP4, 1, false), 20 + 80, |
| 152 |
"4bpp 16px tiles need two words a tile: 100"); |
| 153 |
check_eq(tile_fetches(BPP8, 1, false), 20 + 160, |
| 154 |
"8bpp 16px tiles need four: 180"); |
| 155 |
} |
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
{ |
| 164 |
check_eq(tile_fetches(BPP8, 0, true), 41 + 162, |
| 165 |
"scrolling 8bpp 8px tiles off a boundary costs one more tile: 203"); |
| 166 |
check_eq(tile_fetches(BPP8, 0, true) - tile_fetches(BPP8, 0, false), 3, |
| 167 |
"which is three extra fetches: one map word and two data words"); |
| 168 |
check_eq(tile_fetches(BPP1, 0, true), 41 + 81, |
| 169 |
"and at 1bpp it is 122"); |
| 170 |
check_eq(tile_fetches(BPP1, 0, true) - tile_fetches(BPP1, 0, false), 2, |
| 171 |
"two extra fetches, because a 1bpp tile row is a single word"); |
| 172 |
} |
| 173 |
|
| 174 |
|
| 175 |
{ |
| 176 |
check_eq(bitmap_fetches(BPP1, 0), 20, "1bpp bitmap: 640/32 = 20 fetches"); |
| 177 |
check_eq(bitmap_fetches(BPP2, 0), 40, "2bpp bitmap: 640/16 = 40"); |
| 178 |
check_eq(bitmap_fetches(BPP4, 0), 80, "4bpp bitmap: 640/8 = 80"); |
| 179 |
check_eq(bitmap_fetches(BPP8, 0), 160, "8bpp bitmap: 640/4 = 160"); |
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
check_eq(bitmap_fetches(BPP8, 1), bitmap_fetches(BPP8, 0), |
| 187 |
"a 320-wide bitmap costs the same bus as a 640-wide one: " |
| 188 |
"halving the width buys VRAM, not bandwidth"); |
| 189 |
check_eq(bitmap_fetches(BPP4, 1), bitmap_fetches(BPP4, 0), |
| 190 |
"and the same at 4bpp"); |
| 191 |
check_eq(bitmap_fetches(BPP1, 1), bitmap_fetches(BPP1, 0), |
| 192 |
"and at 1bpp"); |
| 193 |
} |
| 194 |
|
| 195 |
|
| 196 |
{ |
| 197 |
vera_bw_layer_t off = tile_layer(BPP8, 0, true); |
| 198 |
off.enabled = false; |
| 199 |
check_eq(vera_bandwidth_layer_line_fetches(&off), 0, |
| 200 |
"a layer switched off in DC_VIDEO fetches nothing"); |
| 201 |
check_eq(vera_bandwidth_layer_line_fetches(NULL), 0, |
| 202 |
"and a null layer is not a crash"); |
| 203 |
} |
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
{ |
| 210 |
const uint32_t two_layers = 2u * bitmap_fetches(BPP8, 1) * VERA_BW_ACCESS_CLOCKS; |
| 211 |
check_eq(two_layers, 640, |
| 212 |
"two 8bpp bitmap layers take 640 of the 800 clocks"); |
| 213 |
check_eq(two_layers + 160, VERA_BW_LINE_CLOCKS, |
| 214 |
"and 160 clocks of 4bpp sprites fills the scanline exactly"); |
| 215 |
} |
| 216 |
|
| 217 |
|
| 218 |
{ |
| 219 |
begin(); |
| 220 |
const vera_bw_layer_t l0 = bitmap_layer(BPP8, 1); |
| 221 |
const vera_bw_layer_t l1 = tile_layer(BPP1, 0, false); |
| 222 |
|
| 223 |
for (uint16_t y = 0; y < 480; y++) |
| 224 |
vera_bandwidth_line(y, &l0, &l1); |
| 225 |
vera_bandwidth_frame_end(1); |
| 226 |
|
| 227 |
vera_bw_frame_t f; |
| 228 |
check(vera_bandwidth_last_frame(&f), "a finished frame is published"); |
| 229 |
check_eq(f.frame, 1, "carrying its ordinal"); |
| 230 |
check_eq(f.lines_active, 480, "with every active line accounted"); |
| 231 |
check_eq(f.layer_fetches[0], 160u * 480u, "layer 0 fetched 160 a line"); |
| 232 |
check_eq(f.layer_fetches[1], 120u * 480u, "layer 1 fetched 120 a line"); |
| 233 |
check_eq(f.layer_bytes[0], 160u * 480u * 4u, |
| 234 |
"and bytes are just fetches times four"); |
| 235 |
check_eq(f.peak_clocks, (160u + 120u) * VERA_BW_ACCESS_CLOCKS, |
| 236 |
"the busiest line wanted 560 of its 800 clocks"); |
| 237 |
check_eq(f.mean_clocks, 560, "and every line was the same, so the mean matches"); |
| 238 |
check_eq(f.p95_clocks, 560, "as does the 95th percentile"); |
| 239 |
check_eq(f.lines_over, 0, "nothing exceeded the scanline window"); |
| 240 |
check_eq(f.layer_peak_fetches[0], 160, "layer 0's peak line is a full one"); |
| 241 |
} |
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
{ |
| 249 |
begin(); |
| 250 |
const vera_bw_layer_t heavy = bitmap_layer(BPP8, 1); |
| 251 |
const vera_bw_layer_t light = bitmap_layer(BPP1, 0); |
| 252 |
vera_bw_layer_t none = bitmap_layer(BPP1, 0); |
| 253 |
none.enabled = false; |
| 254 |
|
| 255 |
vera_bandwidth_line(100, &heavy, &none); |
| 256 |
vera_bandwidth_line(100, &light, &none); |
| 257 |
vera_bandwidth_frame_end(2); |
| 258 |
|
| 259 |
vera_bw_frame_t f; |
| 260 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 261 |
check_eq(f.layer_fetches[0], 20, |
| 262 |
"a re-rendered line keeps the last pass, not the sum of passes"); |
| 263 |
check_eq(f.lines_active, 1, "and is still one line"); |
| 264 |
} |
| 265 |
|
| 266 |
|
| 267 |
{ |
| 268 |
begin(); |
| 269 |
for (int i = 0; i < 100; i++) |
| 270 |
vera_bandwidth_note_port(true, 1, 50); |
| 271 |
for (int i = 0; i < 30; i++) |
| 272 |
vera_bandwidth_note_port(false, 1, 50); |
| 273 |
vera_bandwidth_frame_end(3); |
| 274 |
|
| 275 |
vera_bw_frame_t f; |
| 276 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 277 |
check_eq(f.port_writes, 100, "100 bytes written through $9F23"); |
| 278 |
check_eq(f.port_reads, 30, "and 30 read back"); |
| 279 |
check_eq(f.port_accesses, 130, "each byte costs one VRAM access"); |
| 280 |
check_eq(f.port_vram_bytes, 130, "and an ordinary write moves one byte"); |
| 281 |
|
| 282 |
|
| 283 |
check_eq(f.peak_line, 50, "port traffic marks the line it landed on"); |
| 284 |
check_eq(f.lines_active, 1, |
| 285 |
"and makes that line active even with both layers off -- a " |
| 286 |
"program blasting VRAM through $9F23 is using the bus, " |
| 287 |
"whatever the display is doing"); |
| 288 |
check_eq(f.peak_clocks, 130u * VERA_BW_ACCESS_CLOCKS, |
| 289 |
"costing two clocks an access like any other client"); |
| 290 |
} |
| 291 |
|
| 292 |
|
| 293 |
{ |
| 294 |
begin(); |
| 295 |
|
| 296 |
|
| 297 |
for (int i = 0; i < 10; i++) { |
| 298 |
vera_bandwidth_note_port(true, 4, 10); |
| 299 |
vera_bandwidth_note_fx_cache_write(10); |
| 300 |
} |
| 301 |
vera_bandwidth_frame_end(4); |
| 302 |
|
| 303 |
vera_bw_frame_t f; |
| 304 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 305 |
check_eq(f.port_writes, 10, "ten CPU stores"); |
| 306 |
check_eq(f.fx_cache_writes, 10, "all of them FX cache writes"); |
| 307 |
check_eq(f.port_vram_bytes, 40, |
| 308 |
"which moved forty bytes: FX multiplies a store fourfold"); |
| 309 |
} |
| 310 |
|
| 311 |
|
| 312 |
{ |
| 313 |
begin(); |
| 314 |
vera_bandwidth_note_port(false, 1, 20); |
| 315 |
vera_bandwidth_note_fx_affine(20); |
| 316 |
vera_bandwidth_frame_end(5); |
| 317 |
|
| 318 |
vera_bw_frame_t f; |
| 319 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 320 |
check_eq(f.fx_affine_fetches, 1, "one affine read"); |
| 321 |
check_eq(f.port_accesses, 2, |
| 322 |
"costing two accesses: the map entry and then the tile"); |
| 323 |
} |
| 324 |
|
| 325 |
|
| 326 |
{ |
| 327 |
begin(); |
| 328 |
const vera_bw_layer_t l0 = bitmap_layer(BPP8, 1); |
| 329 |
const vera_bw_layer_t l1 = bitmap_layer(BPP8, 1); |
| 330 |
vera_bandwidth_line(7, &l0, &l1); |
| 331 |
for (int i = 0; i < 100; i++) |
| 332 |
vera_bandwidth_note_port(true, 1, 7); |
| 333 |
vera_bandwidth_frame_end(6); |
| 334 |
|
| 335 |
vera_bw_frame_t f; |
| 336 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 337 |
check_eq(f.peak_clocks, 840, "layers and CPU together wanted 840 clocks"); |
| 338 |
check(f.peak_clocks > VERA_BW_LINE_CLOCKS, |
| 339 |
"which is more than the scanline has"); |
| 340 |
check_eq(f.lines_over, 1, |
| 341 |
"and that is reported rather than clamped, because it is the " |
| 342 |
"whole point: sprites are last on the bus and get what is left"); |
| 343 |
} |
| 344 |
|
| 345 |
|
| 346 |
{ |
| 347 |
begin(); |
| 348 |
vera_bw_layer_t none = bitmap_layer(BPP1, 0); |
| 349 |
none.enabled = false; |
| 350 |
const vera_bw_layer_t light = bitmap_layer(BPP1, 0); |
| 351 |
const vera_bw_layer_t heavy = bitmap_layer(BPP8, 1); |
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
for (uint16_t y = 0; y < 99; y++) |
| 356 |
vera_bandwidth_line(y, &light, &none); |
| 357 |
vera_bandwidth_line(99, &heavy, &none); |
| 358 |
vera_bandwidth_frame_end(7); |
| 359 |
|
| 360 |
vera_bw_frame_t f; |
| 361 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 362 |
check_eq(f.lines_active, 100, "a hundred lines rendered"); |
| 363 |
check_eq(f.peak_clocks, 320, "the loud line is the peak"); |
| 364 |
check_eq(f.peak_line, 99, "and is identified"); |
| 365 |
check_eq(f.p95_clocks, 40, |
| 366 |
"the 95th percentile ignores a single outlier, which is why " |
| 367 |
"the peak is reported next to it and not instead of it"); |
| 368 |
check(f.mean_clocks < 50, "and the mean stays near the quiet lines"); |
| 369 |
} |
| 370 |
|
| 371 |
|
| 372 |
{ |
| 373 |
begin(); |
| 374 |
const vera_bw_layer_t l0 = bitmap_layer(BPP4, 0); |
| 375 |
vera_bw_layer_t none = bitmap_layer(BPP1, 0); |
| 376 |
none.enabled = false; |
| 377 |
vera_bandwidth_line(3, &l0, &none); |
| 378 |
vera_bandwidth_note_port(true, 1, 3); |
| 379 |
vera_bandwidth_frame_end(8); |
| 380 |
|
| 381 |
uint16_t n = 0; |
| 382 |
const vera_bw_line_t *lines = vera_bandwidth_last_lines(&n); |
| 383 |
check(lines != NULL, "per-line detail is published for the panel"); |
| 384 |
check_eq(n, VERA_BW_LINES, "covering every active scanline"); |
| 385 |
check(lines[3].rendered, "the line we drew is marked rendered"); |
| 386 |
check_eq(lines[3].layer_fetches[0], 80, "with its fetch count"); |
| 387 |
check_eq(lines[3].port_accesses, 1, "and the port access on it"); |
| 388 |
check_eq(vera_bw_line_clocks(&lines[3]), 81u * VERA_BW_ACCESS_CLOCKS, |
| 389 |
"line clocks are derived from both, so they cannot drift apart"); |
| 390 |
check(!lines[4].rendered, "and one we did not is not"); |
| 391 |
} |
| 392 |
|
| 393 |
|
| 394 |
|
| 395 |
|
| 396 |
|
| 397 |
|
| 398 |
|
| 399 |
|
| 400 |
|
| 401 |
{ |
| 402 |
begin(); |
| 403 |
const vera_bw_layer_t l0 = bitmap_layer(BPP4, 0); |
| 404 |
vera_bw_layer_t none = bitmap_layer(BPP1, 0); |
| 405 |
none.enabled = false; |
| 406 |
|
| 407 |
vera_bandwidth_line(200, &l0, &none); |
| 408 |
for (int i = 0; i < 20; i++) |
| 409 |
vera_bandwidth_note_port(true, 1, 200); |
| 410 |
vera_bandwidth_frame_end(11); |
| 411 |
|
| 412 |
vera_bw_frame_t f; |
| 413 |
check(vera_bandwidth_last_frame(&f), "the frame published"); |
| 414 |
check_eq(f.lines_active, 1, |
| 415 |
"layer and port traffic on one scanline is one active line"); |
| 416 |
check_eq(f.peak_line, 200, "and the peak is that line"); |
| 417 |
check_eq(f.peak_clocks, (80u + 20u) * VERA_BW_ACCESS_CLOCKS, |
| 418 |
"with both contributions summed into it"); |
| 419 |
} |
| 420 |
|
| 421 |
|
| 422 |
|
| 423 |
|
| 424 |
|
| 425 |
|
| 426 |
|
| 427 |
{ |
| 428 |
|
| 429 |
check_eq(vera_bandwidth_sprite_bus_clocks(64, 0), 16, |
| 430 |
"a 64-wide 4bpp sprite fetches 8 words: 16 bus clocks"); |
| 431 |
check_eq(vera_bandwidth_sprite_bus_clocks(8, 0), 2, |
| 432 |
"an 8-wide 4bpp sprite is one word"); |
| 433 |
|
| 434 |
check_eq(vera_bandwidth_sprite_bus_clocks(64, 1), 32, |
| 435 |
"the same sprite at 8bpp costs twice the bus"); |
| 436 |
check_eq(vera_bandwidth_sprite_bus_clocks(8, 1), 4, "and an 8-wide one is two words"); |
| 437 |
|
| 438 |
|
| 439 |
check_eq(vera_bandwidth_sprite_bus_clocks(12, 0), 4, |
| 440 |
"a 12-wide 4bpp sprite still pays for its partial last word"); |
| 441 |
|
| 442 |
|
| 443 |
|
| 444 |
|
| 445 |
|
| 446 |
|
| 447 |
const uint16_t words_in_a_full_line = 798 / 10; |
| 448 |
const uint32_t bus = (uint32_t)words_in_a_full_line * VERA_BW_ACCESS_CLOCKS; |
| 449 |
check_eq(bus, 158, |
| 450 |
"a full 4bpp sprite line is about 158 bus clocks, not 798 -- " |
| 451 |
"which is why the two numbers must never be subtracted"); |
| 452 |
check(bus < VERA_BW_LINE_CLOCKS / 4, |
| 453 |
"sprite bus time is a small share of the scanline, however close " |
| 454 |
"to its render-time ceiling the line runs"); |
| 455 |
|
| 456 |
|
| 457 |
|
| 458 |
const uint16_t seventy_words = 700 / 10; |
| 459 |
check(vera_bandwidth_sprite_bus_clocks((uint16_t)(seventy_words * 8), 0) <= 160, |
| 460 |
"700 render clocks of 4bpp sprites fit inside 160 free bus " |
| 461 |
"clocks, so comparing render time against bus time would warn " |
| 462 |
"about a line that is comfortably fine"); |
| 463 |
} |
| 464 |
|
| 465 |
|
| 466 |
{ |
| 467 |
vera_bandwidth_set_enabled(false); |
| 468 |
check(!vera_bandwidth_is_enabled(), "accounting is off"); |
| 469 |
|
| 470 |
const vera_bw_layer_t l0 = bitmap_layer(BPP8, 1); |
| 471 |
vera_bandwidth_line(0, &l0, &l0); |
| 472 |
vera_bandwidth_note_port(true, 1, 0); |
| 473 |
vera_bandwidth_frame_end(9); |
| 474 |
|
| 475 |
vera_bw_frame_t f; |
| 476 |
check(!vera_bandwidth_last_frame(&f), |
| 477 |
"and nothing is recorded while it is"); |
| 478 |
} |
| 479 |
|
| 480 |
|
| 481 |
{ |
| 482 |
vera_bandwidth_set_enabled(false); |
| 483 |
vera_bandwidth_arm(VERA_BW_OWNER_UI, true); |
| 484 |
check(vera_bandwidth_is_enabled(), "the panel can switch accounting on"); |
| 485 |
|
| 486 |
vera_bandwidth_arm(VERA_BW_OWNER_DAP, true); |
| 487 |
check(vera_bandwidth_owner_wants(VERA_BW_OWNER_DAP), "so can a DAP client"); |
| 488 |
|
| 489 |
vera_bandwidth_arm(VERA_BW_OWNER_UI, false); |
| 490 |
check(vera_bandwidth_is_enabled(), |
| 491 |
"closing the panel does not strand the client"); |
| 492 |
check(!vera_bandwidth_owner_wants(VERA_BW_OWNER_UI), |
| 493 |
"though the panel no longer wants it"); |
| 494 |
|
| 495 |
vera_bandwidth_arm(VERA_BW_OWNER_DAP, false); |
| 496 |
check(!vera_bandwidth_is_enabled(), |
| 497 |
"and it stops once nobody is asking"); |
| 498 |
} |
| 499 |
|
| 500 |
|
| 501 |
{ |
| 502 |
vera_bandwidth_configure(525); |
| 503 |
check_eq(vera_bandwidth_scanlines_per_frame(), 525, "VGA scans 525 lines"); |
| 504 |
vera_bandwidth_configure(0); |
| 505 |
check_eq(vera_bandwidth_scanlines_per_frame(), 525, |
| 506 |
"and a nonsense value is ignored rather than believed"); |
| 507 |
} |
| 508 |
|
| 509 |
|
| 510 |
{ |
| 511 |
begin(); |
| 512 |
const vera_bw_layer_t l0 = bitmap_layer(BPP8, 1); |
| 513 |
vera_bandwidth_line(0, &l0, &l0); |
| 514 |
vera_bandwidth_frame_end(10); |
| 515 |
|
| 516 |
vera_bw_frame_t f; |
| 517 |
check(vera_bandwidth_last_frame(&f), "a frame is there to forget"); |
| 518 |
vera_bandwidth_reset(); |
| 519 |
check(!vera_bandwidth_last_frame(&f), "reset forgets it"); |
| 520 |
check_eq(vera_bandwidth_scanlines_per_frame(), 525, |
| 521 |
"while leaving the machine configuration alone"); |
| 522 |
|
| 523 |
vera_bandwidth_set_enabled(false); |
| 524 |
} |
| 525 |
|
| 526 |
return x16_test_summary("vera_bandwidth"); |
| 527 |
} |