void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_points, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader) { if (PokeData.size() < num_points * 6) { PokeData.resize(num_points * 6); } for (size_t i = 0; i < num_points; i++) { // generate quad from the single point (clip-space coordinates) const EfbPokeData point = points[i]; float x1 = float(point.x) * 2.0f / EFB_WIDTH - 1.0f; float y1 = -float(point.y) * 2.0f / EFB_HEIGHT + 1.0f; float x2 = float(point.x + 1) * 2.0f / EFB_WIDTH - 1.0f; float y2 = -float(point.y + 1) * 2.0f / EFB_HEIGHT + 1.0f; float z = (type == POKE_Z) ? (1.0f - float(point.data & 0xFFFFFF) / 16777216.0f) : 0.0f; u32 col = (type == POKE_Z) ? 0 : RGBA8ToBGRA8(point.data); // quad -> triangles Q2DVertex* vertex = &PokeData[i * 6]; vertex[0] = { x1, y1, z, 1.0, col }; vertex[1] = { x2, y1, z, 1.0, col }; vertex[2] = { x1, y2, z, 1.0, col }; vertex[3] = { x1, y2, z, 1.0, col }; vertex[4] = { x2, y1, z, 1.0, col }; vertex[5] = { x2, y2, z, 1.0, col }; if (type == POKE_COLOR) FramebufferManager::SetEFBCachedColor(point.x, point.y, col); else FramebufferManager::SetEFBCachedDepth(point.x, point.y, u32(z * 0xFFFFFF)); } D3D::ChangeVertexShader(Vshader); D3D::ChangePixelShader(PShader); D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, ((UINT)num_points) * 2, PokeData.data(), sizeof(Q2DVertex)); RestoreShaders(); }
void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_points) { const size_t COL_QUAD_SIZE = sizeof(ColVertex) * 6; // Set common state stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader()); stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader()); stateman->SetPixelShader(PixelShaderCache::GetClearProgram()); stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout()); stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); stateman->SetVertexBuffer(util_vbuf->GetBuffer(), sizeof(ColVertex), 0); stateman->Apply(); // if drawing a large number of points at once, this will have to be split into multiple passes. size_t points_per_draw = util_vbuf->GetSize() / COL_QUAD_SIZE; size_t current_point_index = 0; while (current_point_index < num_points) { size_t points_to_draw = std::min(num_points - current_point_index, points_per_draw); size_t required_bytes = COL_QUAD_SIZE * points_to_draw; // map and reserve enough buffer space for this draw void* buffer_ptr; int base_vertex_index = util_vbuf->BeginAppendData(&buffer_ptr, (int)required_bytes, sizeof(ColVertex)); // generate quads for each efb point ColVertex* base_vertex_ptr = reinterpret_cast<ColVertex*>(buffer_ptr); for (size_t i = 0; i < points_to_draw; i++) { // generate quad from the single point (clip-space coordinates) const EfbPokeData point = points[current_point_index]; float x1 = float(point.x) * 2.0f / EFB_WIDTH - 1.0f; float y1 = -float(point.y) * 2.0f / EFB_HEIGHT + 1.0f; float x2 = float(point.x + 1) * 2.0f / EFB_WIDTH - 1.0f; float y2 = -float(point.y + 1) * 2.0f / EFB_HEIGHT + 1.0f; float z = (type == POKE_Z) ? (1.0f - float(point.data & 0xFFFFFF) / 16777216.0f) : 0.0f; u32 col = (type == POKE_Z) ? 0 : RGBA8ToBGRA8(point.data); current_point_index++; // quad -> triangles ColVertex* vertex = &base_vertex_ptr[i * 6]; InitColVertex(&vertex[0], x1, y1, z, col); InitColVertex(&vertex[1], x2, y1, z, col); InitColVertex(&vertex[2], x1, y2, z, col); InitColVertex(&vertex[3], x1, y2, z, col); InitColVertex(&vertex[4], x2, y1, z, col); InitColVertex(&vertex[5], x2, y2, z, col); if (type == POKE_COLOR) FramebufferManager::SetEFBCachedColor(point.x, point.y, col); else FramebufferManager::SetEFBCachedDepth(point.x, point.y, z); } // unmap the util buffer, and issue the draw util_vbuf->EndAppendData(); context->Draw(6 * (UINT)points_to_draw, base_vertex_index); } stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader()); }