| 2490 | } |
| 2491 | |
| 2492 | void GSState::FlushPrim() |
| 2493 | { |
| 2494 | if (m_index->tail > 0) |
| 2495 | { |
| 2496 | GL_REG("FlushPrim ctxt %d", PRIM->CTXT); |
| 2497 | |
| 2498 | // clear texture cache flushed flag, since we're reading from it |
| 2499 | m_texflush_flag = PRIM->TME ? false : m_texflush_flag; |
| 2500 | |
| 2501 | // internal frame rate detection based on sprite blits to the display framebuffer |
| 2502 | { |
| 2503 | const u32 FRAME_FBP = m_context->FRAME.FBP; |
| 2504 | if ((m_regs->DISP[0].DISPFB.FBP == FRAME_FBP && m_regs->PMODE.EN1) || |
| 2505 | (m_regs->DISP[1].DISPFB.FBP == FRAME_FBP && m_regs->PMODE.EN2)) |
| 2506 | { |
| 2507 | g_perfmon.AddDisplayFramebufferSpriteBlit(); |
| 2508 | } |
| 2509 | } |
| 2510 | |
| 2511 | GSVertex buff[2]; |
| 2512 | s_n++; |
| 2513 | |
| 2514 | const u32 head = m_vertex->head; |
| 2515 | const u32 tail = m_vertex->tail; |
| 2516 | const u32 next = m_vertex->next; |
| 2517 | u32 unused = 0; |
| 2518 | |
| 2519 | if (tail > head) |
| 2520 | { |
| 2521 | switch (PRIM->PRIM) |
| 2522 | { |
| 2523 | case GS_POINTLIST: |
| 2524 | pxAssert(0); |
| 2525 | break; |
| 2526 | case GS_LINELIST: |
| 2527 | case GS_LINESTRIP: |
| 2528 | case GS_SPRITE: |
| 2529 | unused = 1; |
| 2530 | buff[0] = m_vertex->buff[tail - 1]; |
| 2531 | break; |
| 2532 | case GS_TRIANGLELIST: |
| 2533 | case GS_TRIANGLESTRIP: |
| 2534 | unused = std::min<u32>(tail - head, 2); |
| 2535 | memcpy(buff, &m_vertex->buff[tail - unused], sizeof(GSVertex) * 2); |
| 2536 | break; |
| 2537 | case GS_TRIANGLEFAN: |
| 2538 | buff[0] = m_vertex->buff[head]; |
| 2539 | unused = 1; |
| 2540 | if (tail - 1 > head) |
| 2541 | { |
| 2542 | buff[1] = m_vertex->buff[tail - 1]; |
| 2543 | unused = 2; |
| 2544 | } |
| 2545 | break; |
| 2546 | case GS_INVALID: |
| 2547 | break; |
| 2548 | default: |
| 2549 | ASSUME(0); |
nothing calls this directly
no test coverage detected