void PerfQuery::WeakFlush() { if (!ShouldEmulate()) return; while (!IsFlushed()) { auto& entry = m_query_buffer[m_query_read_pos]; UINT64 result = 0; HRESULT hr = D3D::context->GetData(entry.query, &result, sizeof(result), D3D11_ASYNC_GETDATA_DONOTFLUSH); if (hr == S_OK) { // NOTE: Reported pixel metrics should be referenced to native resolution m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight(); m_query_read_pos = (m_query_read_pos + 1) % ArraySize(m_query_buffer); --m_query_count; } else { break; } } }
// TODO: could selectively flush things, but I don't think that will do much void PerfQuery::FlushResults() { if (!ShouldEmulate()) return; while (!IsFlushed()) FlushOne(); }
bool qEnvApache::SetReplyCode(int reply) { if (!IsFlushed()) { GetRequest()->status = reply; return true; } return false; }
void PerfQuery::NonBlockingPartialFlush() { if (IsFlushed()) return; // Submit a command buffer in the background if the front query is not bound to one. // Ideally this will complete before the buffer fills. if (m_query_buffer[m_query_read_pos].pending_fence == VK_NULL_HANDLE) Util::ExecuteCurrentCommandsAndRestoreState(true, false); }
void PerfQuery::NonBlockingPartialFlush() { if (IsFlushed()) return; // Submit a command buffer in the background if the front query is not bound to one. // Ideally this will complete before the buffer fills. if (m_query_buffer[m_query_read_pos].pending_fence == VK_NULL_HANDLE) Renderer::GetInstance()->ExecuteCommandBuffer(true, false); }
bool qEnvApache::AppendHeader(const char *str, const char *val) { if (!IsFlushed()) { ap_table_add(GetRequest()->headers_out, str, val); if (!stricmp(str,"set-cookie")) ap_table_add(GetRequest()->err_headers_out, str, val); return true; } return false; }
bool qEnvApache::SetHeader(const char *str, const char *val) { if (!IsFlushed()) { ap_table_set(GetRequest()->headers_out, str, val); if (!stricmp(str,"content-type")) { myReq->content_type = ap_pstrdup(myReq->pool, val); } else if (!stricmp(str,"set-cookie")) ap_table_set(GetRequest()->err_headers_out, str, val); return true; } return false; }
void PerfQuery::WeakFlush() { UINT64 completed_fence = m_tracking_fence->GetCompletedValue(); while (!IsFlushed()) { ActiveQuery& entry = m_query_buffer[m_query_read_pos]; if (entry.fence_value > completed_fence) break; FlushOne(); } }
void PerfQueryGLESNV::WeakFlush() { while (!IsFlushed()) { auto& entry = m_query_buffer[m_query_read_pos]; GLuint result = GL_FALSE; glGetOcclusionQueryuivNV(entry.query_id, GL_PIXEL_COUNT_AVAILABLE_NV, &result); if (GL_TRUE == result) { FlushOne(); } else { break; } } }
void PerfQueryGL::WeakFlush() { while (!IsFlushed()) { auto& entry = m_query_buffer[m_query_read_pos]; GLuint result = GL_FALSE; glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT_AVAILABLE, &result); if (GL_TRUE == result) { FlushOne(); } else { break; } } }
void PerfQuery::BlockingPartialFlush() { if (IsFlushed()) return; // If the first pending query is needing command buffer execution, do that. ActiveQuery& entry = m_query_buffer[m_query_read_pos]; if (entry.pending_fence == VK_NULL_HANDLE) { // This will callback OnCommandBufferQueued which will set the fence on the entry. // We wait for completion, which will also call OnCommandBufferExecuted, and clear the fence. Util::ExecuteCurrentCommandsAndRestoreState(false, true); } else { // The command buffer has been submitted, but is awaiting completion. // Wait for the fence to complete, which will call OnCommandBufferExecuted. g_command_buffer_mgr->WaitForFence(entry.pending_fence); } }
void PerfQuery::FlushResults() { if (IsFlushed()) return; // Find the fence value we have to wait for. UINT64 last_fence_value = FindLastPendingFenceValue(); if (last_fence_value == m_next_fence_value) D3D::command_list_mgr->ExecuteQueuedWork(false); // Wait for all queries to be resolved. D3D::command_list_mgr->WaitOnCPUForFence(m_tracking_fence, last_fence_value); // Map the whole readback buffer. Shouldn't have much overhead, and saves taking the // wrapped-around cases into consideration. void* readback_buffer_map; D3D12_RANGE read_range = {0, QUERY_READBACK_BUFFER_SIZE}; CheckHR(m_query_readback_buffer->Map(0, &read_range, &readback_buffer_map)); // Read all pending queries. while (m_query_count > 0) { ActiveQuery& entry = m_query_buffer[m_query_read_pos]; UINT64 result; memcpy(&result, reinterpret_cast<u8*>(readback_buffer_map) + sizeof(UINT64) * m_query_read_pos, sizeof(UINT64)); // NOTE: Reported pixel metrics should be referenced to native resolution m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight()); m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size(); m_query_count--; } D3D12_RANGE write_range = {}; m_query_readback_buffer->Unmap(0, &write_range); }
// TODO: could selectively flush things, but I don't think that will do much void PerfQueryGLESNV::FlushResults() { while (!IsFlushed()) FlushOne(); }
void PerfQuery::FlushResults() { while (!IsFlushed()) BlockingPartialFlush(); }
void PerfQuery::FlushResults() { while (!IsFlushed()) PartialFlush(true); }