1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-02 04:29:14 +01:00

[d3d11] Added test case for occlusion queries and small improvements

This commit is contained in:
Philip Rebohle 2018-02-19 11:27:14 +01:00
parent 675a629ae5
commit e89c7e9276
11 changed files with 95 additions and 44 deletions

View File

@ -21,7 +21,7 @@ namespace dxvk {
m_msState.sampleMask = 0; // Set during bind m_msState.sampleMask = 0; // Set during bind
m_msState.enableAlphaToCoverage = desc.AlphaToCoverageEnable; m_msState.enableAlphaToCoverage = desc.AlphaToCoverageEnable;
m_msState.enableAlphaToOne = VK_FALSE; m_msState.enableAlphaToOne = VK_FALSE;
m_msState.enableSampleShading = VK_TRUE; m_msState.enableSampleShading = VK_FALSE;
m_msState.minSampleShading = 0.0f; m_msState.minSampleShading = 0.0f;
// In 11_0, there is no logic op state. Later versions // In 11_0, there is no logic op state. Later versions

View File

@ -41,21 +41,23 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
m_parent->FlushInitContext(); if (m_csChunk->commandCount() != 0) {
m_drawCount = 0; m_parent->FlushInitContext();
m_drawCount = 0;
// Add commands to flush the threaded
// context, then flush the command list
EmitCs([dev = m_device] (DxvkContext* ctx) {
dev->submitCommandList(
ctx->endRecording(),
nullptr, nullptr);
ctx->beginRecording( // Add commands to flush the threaded
dev->createCommandList()); // context, then flush the command list
}); EmitCs([dev = m_device] (DxvkContext* ctx) {
dev->submitCommandList(
FlushCsChunk(); ctx->endRecording(),
nullptr, nullptr);
ctx->beginRecording(
dev->createCommandList());
});
FlushCsChunk();
}
} }

View File

@ -13,19 +13,27 @@ namespace dxvk {
break; break;
case D3D11_QUERY_OCCLUSION: case D3D11_QUERY_OCCLUSION:
m_query = new DxvkQuery(
VK_QUERY_TYPE_OCCLUSION,
VK_QUERY_CONTROL_PRECISE_BIT);
break;
case D3D11_QUERY_OCCLUSION_PREDICATE: case D3D11_QUERY_OCCLUSION_PREDICATE:
m_query = new DxvkQuery(VK_QUERY_TYPE_OCCLUSION); m_query = new DxvkQuery(
VK_QUERY_TYPE_OCCLUSION, 0);
break; break;
case D3D11_QUERY_TIMESTAMP: case D3D11_QUERY_TIMESTAMP:
m_query = new DxvkQuery(VK_QUERY_TYPE_TIMESTAMP); m_query = new DxvkQuery(
VK_QUERY_TYPE_TIMESTAMP, 0);
break; break;
case D3D11_QUERY_TIMESTAMP_DISJOINT: case D3D11_QUERY_TIMESTAMP_DISJOINT:
break; break;
case D3D11_QUERY_PIPELINE_STATISTICS: case D3D11_QUERY_PIPELINE_STATISTICS:
m_query = new DxvkQuery(VK_QUERY_TYPE_PIPELINE_STATISTICS); m_query = new DxvkQuery(
VK_QUERY_TYPE_PIPELINE_STATISTICS, 0);
break; break;
default: default:

View File

@ -73,7 +73,7 @@ namespace dxvk {
m_cmd->cmdBeginQuery( m_cmd->cmdBeginQuery(
handle.queryPool, handle.queryPool,
handle.queryId, handle.queryId,
0); handle.flags);
query.query->beginRecording(query.revision); query.query->beginRecording(query.revision);
this->insertActiveQuery(query); this->insertActiveQuery(query);
@ -1636,7 +1636,7 @@ namespace dxvk {
DxvkQueryHandle DxvkContext::allocQuery(const DxvkQueryRevision& query) { DxvkQueryHandle DxvkContext::allocQuery(const DxvkQueryRevision& query) {
const VkQueryType queryType = query.query->type(); const VkQueryType queryType = query.query->type();
DxvkQueryHandle queryHandle = { VK_NULL_HANDLE, 0 }; DxvkQueryHandle queryHandle = DxvkQueryHandle();
Rc<DxvkQueryPool> queryPool = m_queryPools[queryType]; Rc<DxvkQueryPool> queryPool = m_queryPools[queryType];
if (queryPool != nullptr) if (queryPool != nullptr)
@ -1681,7 +1681,7 @@ namespace dxvk {
m_cmd->cmdBeginQuery( m_cmd->cmdBeginQuery(
handle.queryPool, handle.queryPool,
handle.queryId, handle.queryId,
0); handle.flags);
} }
} }

View File

@ -17,10 +17,8 @@ namespace dxvk {
void DxvkEvent::signal(uint32_t revision) { void DxvkEvent::signal(uint32_t revision) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
if (m_revision == revision) { if (m_revision == revision)
m_status = DxvkEventStatus::Signaled; m_status = DxvkEventStatus::Signaled;
m_signal.notify_one();
}
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <condition_variable>
#include <mutex> #include <mutex>
#include "dxvk_include.h" #include "dxvk_include.h"
@ -49,8 +48,7 @@ namespace dxvk {
private: private:
std::mutex m_mutex; std::mutex m_mutex;
std::condition_variable m_signal;
DxvkEventStatus m_status = DxvkEventStatus::Reset; DxvkEventStatus m_status = DxvkEventStatus::Reset;
uint32_t m_revision = 0; uint32_t m_revision = 0;

View File

@ -2,8 +2,10 @@
namespace dxvk { namespace dxvk {
DxvkQuery::DxvkQuery(VkQueryType type) DxvkQuery::DxvkQuery(
: m_type(type) { VkQueryType type,
VkQueryControlFlags flags)
: m_type(type), m_flags(flags) {
} }
@ -57,7 +59,6 @@ namespace dxvk {
m_status = DxvkQueryStatus::Pending; m_status = DxvkQueryStatus::Pending;
} else { } else {
m_status = DxvkQueryStatus::Available; m_status = DxvkQueryStatus::Available;
m_signal.notify_all();
} }
m_handle = DxvkQueryHandle(); m_handle = DxvkQueryHandle();
@ -110,10 +111,8 @@ namespace dxvk {
Logger::err(str::format("DxvkQuery: Unhandled query type: ", m_type)); Logger::err(str::format("DxvkQuery: Unhandled query type: ", m_type));
} }
if (++m_queryIndex == m_queryCount && m_status == DxvkQueryStatus::Pending) { if (++m_queryIndex == m_queryCount && m_status == DxvkQueryStatus::Pending)
m_status = DxvkQueryStatus::Available; m_status = DxvkQueryStatus::Available;
m_signal.notify_all();
}
} }
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <condition_variable>
#include <mutex> #include <mutex>
#include "dxvk_limits.h" #include "dxvk_limits.h"
@ -78,8 +77,9 @@ namespace dxvk {
* index of a single Vulkan query. * index of a single Vulkan query.
*/ */
struct DxvkQueryHandle { struct DxvkQueryHandle {
VkQueryPool queryPool = VK_NULL_HANDLE; VkQueryPool queryPool = VK_NULL_HANDLE;
uint32_t queryId = 0; uint32_t queryId = 0;
VkQueryControlFlags flags = 0;
}; };
/** /**
@ -93,7 +93,9 @@ namespace dxvk {
public: public:
DxvkQuery(VkQueryType type); DxvkQuery(
VkQueryType type,
VkQueryControlFlags flags);
~DxvkQuery(); ~DxvkQuery();
/** /**
@ -104,6 +106,17 @@ namespace dxvk {
return m_type; return m_type;
} }
/**
* \brief Query control flags
*
* Flags that will be applied when
* calling \c vkCmdBeginQuery.
* \returns Query control flags
*/
VkQueryControlFlags flags() const {
return m_flags;
}
/** /**
* \brief Resets the query object * \brief Resets the query object
* *
@ -172,10 +185,10 @@ namespace dxvk {
private: private:
const VkQueryType m_type; const VkQueryType m_type;
const VkQueryControlFlags m_flags;
std::mutex m_mutex; std::mutex m_mutex;
std::condition_variable m_signal;
DxvkQueryStatus m_status = DxvkQueryStatus::Reset; DxvkQueryStatus m_status = DxvkQueryStatus::Reset;
DxvkQueryData m_data = {}; DxvkQueryData m_data = {};

View File

@ -48,7 +48,10 @@ namespace dxvk {
const uint32_t queryIndex = m_queryRangeOffset + m_queryRangeLength; const uint32_t queryIndex = m_queryRangeOffset + m_queryRangeLength;
if (queryIndex < m_queryCount) { if (queryIndex < m_queryCount) {
const DxvkQueryHandle result = { m_queryPool, queryIndex }; DxvkQueryHandle result;
result.queryPool = m_queryPool;
result.queryId = queryIndex;
result.flags = query.query->flags();
query.query->associateQuery(query.revision, result); query.query->associateQuery(query.revision, result);
m_queries.at(queryIndex) = query; m_queries.at(queryIndex) = query;
@ -56,7 +59,7 @@ namespace dxvk {
m_queryRangeLength += 1; m_queryRangeLength += 1;
return result; return result;
} else { } else {
return DxvkQueryHandle { VK_NULL_HANDLE, 0 }; return DxvkQueryHandle();
} }
} }

View File

@ -9,8 +9,6 @@ namespace dxvk {
/** /**
* \brief Query range * \brief Query range
*
*
*/ */
struct DxvkQueryRange { struct DxvkQueryRange {
Rc<DxvkQueryPool> queryPool; Rc<DxvkQueryPool> queryPool;

View File

@ -4,6 +4,8 @@
#include <windows.h> #include <windows.h>
#include <windowsx.h> #include <windowsx.h>
#include <thread>
#include "../test_utils.h" #include "../test_utils.h"
using namespace dxvk; using namespace dxvk;
@ -242,6 +244,12 @@ public:
&m_vertexFormat))) &m_vertexFormat)))
throw DxvkError("Failed to create input layout"); throw DxvkError("Failed to create input layout");
D3D11_QUERY_DESC queryDesc;
queryDesc.Query = D3D11_QUERY_OCCLUSION;
queryDesc.MiscFlags = 0;
if (FAILED(m_device->CreateQuery(&queryDesc, &m_query)))
throw DxvkError("Failed to create occlusion query");
} }
@ -275,11 +283,13 @@ public:
UINT vsOffset = 0; UINT vsOffset = 0;
// Test normal draws with base vertex // Test normal draws with base vertex
m_context->Begin(m_query.ptr());
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_vertexFormat.ptr()); m_context->IASetInputLayout(m_vertexFormat.ptr());
m_context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &vsStride, &vsOffset); m_context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &vsStride, &vsOffset);
m_context->Draw(3, 0); m_context->Draw(3, 0);
m_context->Draw(3, 3); m_context->Draw(3, 3);
m_context->End(m_query.ptr());
// Test instanced draws with base instance and base vertex // Test instanced draws with base instance and base vertex
vsOffset = 6 * sizeof(Vertex); vsOffset = 6 * sizeof(Vertex);
@ -302,6 +312,26 @@ public:
m_context->OMSetRenderTargets(0, nullptr, nullptr); m_context->OMSetRenderTargets(0, nullptr, nullptr);
m_swapChain->Present(0, 0); m_swapChain->Present(0, 0);
// Test query results
while (true) {
UINT64 samplesPassed = 0;
UINT queryStatus = m_context->GetData(
m_query.ptr(), &samplesPassed, sizeof(samplesPassed),
D3D11_ASYNC_GETDATA_DONOTFLUSH);
if (queryStatus == S_OK) {
if (samplesPassed == 0)
std::cerr << "Occlusion query returned 0 samples" << std::endl;
break;
} else if (queryStatus == S_FALSE) {
std::this_thread::yield();
} else {
std::cerr << "Occlusion query failed" << std::endl;
break;
}
}
} }
@ -354,6 +384,8 @@ private:
Com<ID3D11VertexShader> m_vertexShader; Com<ID3D11VertexShader> m_vertexShader;
Com<ID3D11PixelShader> m_pixelShader; Com<ID3D11PixelShader> m_pixelShader;
Com<ID3D11Query> m_query;
D3D_FEATURE_LEVEL m_featureLevel; D3D_FEATURE_LEVEL m_featureLevel;
}; };