1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 19:24:12 +01:00

[d3d11] Use an array for query and event objects

We're going to need multiple queries to implement certain query types.
This commit is contained in:
Philip Rebohle 2019-06-16 16:53:11 +02:00
parent fd1b5c8eb9
commit 1c718402f8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 41 additions and 40 deletions

View File

@ -13,22 +13,22 @@ namespace dxvk {
switch (m_desc.Query) { switch (m_desc.Query) {
case D3D11_QUERY_EVENT: case D3D11_QUERY_EVENT:
m_event = dxvkDevice->createGpuEvent(); m_event[0] = dxvkDevice->createGpuEvent();
break; break;
case D3D11_QUERY_OCCLUSION: case D3D11_QUERY_OCCLUSION:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_OCCLUSION, VK_QUERY_TYPE_OCCLUSION,
VK_QUERY_CONTROL_PRECISE_BIT, 0); VK_QUERY_CONTROL_PRECISE_BIT, 0);
break; break;
case D3D11_QUERY_OCCLUSION_PREDICATE: case D3D11_QUERY_OCCLUSION_PREDICATE:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_OCCLUSION, 0, 0); VK_QUERY_TYPE_OCCLUSION, 0, 0);
break; break;
case D3D11_QUERY_TIMESTAMP: case D3D11_QUERY_TIMESTAMP:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_TIMESTAMP, 0, 0); VK_QUERY_TYPE_TIMESTAMP, 0, 0);
break; break;
@ -36,7 +36,7 @@ namespace dxvk {
break; break;
case D3D11_QUERY_PIPELINE_STATISTICS: case D3D11_QUERY_PIPELINE_STATISTICS:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_PIPELINE_STATISTICS, 0, 0); VK_QUERY_TYPE_PIPELINE_STATISTICS, 0, 0);
break; break;
@ -47,25 +47,25 @@ namespace dxvk {
// FIXME it is technically incorrect to map // FIXME it is technically incorrect to map
// SO_OVERFLOW_PREDICATE to the first stream, // SO_OVERFLOW_PREDICATE to the first stream,
// but this is good enough for D3D10 behaviour // but this is good enough for D3D10 behaviour
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 0); VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 0);
break; break;
case D3D11_QUERY_SO_STATISTICS_STREAM1: case D3D11_QUERY_SO_STATISTICS_STREAM1:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 1); VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 1);
break; break;
case D3D11_QUERY_SO_STATISTICS_STREAM2: case D3D11_QUERY_SO_STATISTICS_STREAM2:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 2); VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 2);
break; break;
case D3D11_QUERY_SO_STATISTICS_STREAM3: case D3D11_QUERY_SO_STATISTICS_STREAM3:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3:
m_query = dxvkDevice->createGpuQuery( m_query[0] = dxvkDevice->createGpuQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 3); VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 3);
break; break;
@ -182,7 +182,7 @@ namespace dxvk {
break; break;
default: default:
ctx->beginQuery(m_query); ctx->beginQuery(m_query[0]);
} }
m_state = D3D11_VK_QUERY_BEGUN; m_state = D3D11_VK_QUERY_BEGUN;
@ -192,11 +192,11 @@ namespace dxvk {
void D3D11Query::End(DxvkContext* ctx) { void D3D11Query::End(DxvkContext* ctx) {
switch (m_desc.Query) { switch (m_desc.Query) {
case D3D11_QUERY_EVENT: case D3D11_QUERY_EVENT:
ctx->signalGpuEvent(m_event); ctx->signalGpuEvent(m_event[0]);
break; break;
case D3D11_QUERY_TIMESTAMP: case D3D11_QUERY_TIMESTAMP:
ctx->writeTimestamp(m_query); ctx->writeTimestamp(m_query[0]);
break; break;
case D3D11_QUERY_TIMESTAMP_DISJOINT: case D3D11_QUERY_TIMESTAMP_DISJOINT:
@ -206,11 +206,11 @@ namespace dxvk {
if (unlikely(m_state != D3D11_VK_QUERY_BEGUN)) if (unlikely(m_state != D3D11_VK_QUERY_BEGUN))
return; return;
ctx->endQuery(m_query); ctx->endQuery(m_query[0]);
} }
if (m_predicate.defined()) if (m_predicate.defined())
ctx->writePredicate(m_predicate, m_query); ctx->writePredicate(m_predicate, m_query[0]);
m_state = D3D11_VK_QUERY_ENDED; m_state = D3D11_VK_QUERY_ENDED;
} }
@ -220,7 +220,7 @@ namespace dxvk {
void* pData, void* pData,
UINT GetDataFlags) { UINT GetDataFlags) {
if (m_desc.Query == D3D11_QUERY_EVENT) { if (m_desc.Query == D3D11_QUERY_EVENT) {
DxvkGpuEventStatus status = m_event->test(); DxvkGpuEventStatus status = m_event[0]->test();
if (status == DxvkGpuEventStatus::Invalid) if (status == DxvkGpuEventStatus::Invalid)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
@ -232,10 +232,10 @@ namespace dxvk {
return signaled ? S_OK : S_FALSE; return signaled ? S_OK : S_FALSE;
} else { } else {
DxvkQueryData queryData = {}; std::array<DxvkQueryData, MaxGpuQueries> queryData = { };
if (m_query != nullptr) { for (uint32_t i = 0; i < MaxGpuQueries && m_query[i] != nullptr; i++) {
DxvkGpuQueryStatus status = m_query->getData(queryData); DxvkGpuQueryStatus status = m_query[i]->getData(queryData[i]);
if (status == DxvkGpuQueryStatus::Invalid if (status == DxvkGpuQueryStatus::Invalid
|| status == DxvkGpuQueryStatus::Failed) || status == DxvkGpuQueryStatus::Failed)
@ -250,15 +250,15 @@ namespace dxvk {
switch (m_desc.Query) { switch (m_desc.Query) {
case D3D11_QUERY_OCCLUSION: case D3D11_QUERY_OCCLUSION:
*static_cast<UINT64*>(pData) = queryData.occlusion.samplesPassed; *static_cast<UINT64*>(pData) = queryData[0].occlusion.samplesPassed;
return S_OK; return S_OK;
case D3D11_QUERY_OCCLUSION_PREDICATE: case D3D11_QUERY_OCCLUSION_PREDICATE:
*static_cast<BOOL*>(pData) = queryData.occlusion.samplesPassed != 0; *static_cast<BOOL*>(pData) = queryData[0].occlusion.samplesPassed != 0;
return S_OK; return S_OK;
case D3D11_QUERY_TIMESTAMP: case D3D11_QUERY_TIMESTAMP:
*static_cast<UINT64*>(pData) = queryData.timestamp.time; *static_cast<UINT64*>(pData) = queryData[0].timestamp.time;
return S_OK; return S_OK;
case D3D11_QUERY_TIMESTAMP_DISJOINT: { case D3D11_QUERY_TIMESTAMP_DISJOINT: {
@ -269,17 +269,17 @@ namespace dxvk {
case D3D11_QUERY_PIPELINE_STATISTICS: { case D3D11_QUERY_PIPELINE_STATISTICS: {
auto data = static_cast<D3D11_QUERY_DATA_PIPELINE_STATISTICS*>(pData); auto data = static_cast<D3D11_QUERY_DATA_PIPELINE_STATISTICS*>(pData);
data->IAVertices = queryData.statistic.iaVertices; data->IAVertices = queryData[0].statistic.iaVertices;
data->IAPrimitives = queryData.statistic.iaPrimitives; data->IAPrimitives = queryData[0].statistic.iaPrimitives;
data->VSInvocations = queryData.statistic.vsInvocations; data->VSInvocations = queryData[0].statistic.vsInvocations;
data->GSInvocations = queryData.statistic.gsInvocations; data->GSInvocations = queryData[0].statistic.gsInvocations;
data->GSPrimitives = queryData.statistic.gsPrimitives; data->GSPrimitives = queryData[0].statistic.gsPrimitives;
data->CInvocations = queryData.statistic.clipInvocations; data->CInvocations = queryData[0].statistic.clipInvocations;
data->CPrimitives = queryData.statistic.clipPrimitives; data->CPrimitives = queryData[0].statistic.clipPrimitives;
data->PSInvocations = queryData.statistic.fsInvocations; data->PSInvocations = queryData[0].statistic.fsInvocations;
data->HSInvocations = queryData.statistic.tcsPatches; data->HSInvocations = queryData[0].statistic.tcsPatches;
data->DSInvocations = queryData.statistic.tesInvocations; data->DSInvocations = queryData[0].statistic.tesInvocations;
data->CSInvocations = queryData.statistic.csInvocations; data->CSInvocations = queryData[0].statistic.csInvocations;
} return S_OK; } return S_OK;
case D3D11_QUERY_SO_STATISTICS: case D3D11_QUERY_SO_STATISTICS:
@ -288,8 +288,8 @@ namespace dxvk {
case D3D11_QUERY_SO_STATISTICS_STREAM2: case D3D11_QUERY_SO_STATISTICS_STREAM2:
case D3D11_QUERY_SO_STATISTICS_STREAM3: { case D3D11_QUERY_SO_STATISTICS_STREAM3: {
auto data = static_cast<D3D11_QUERY_DATA_SO_STATISTICS*>(pData); auto data = static_cast<D3D11_QUERY_DATA_SO_STATISTICS*>(pData);
data->NumPrimitivesWritten = queryData.xfbStream.primitivesWritten; data->NumPrimitivesWritten = queryData[0].xfbStream.primitivesWritten;
data->PrimitivesStorageNeeded = queryData.xfbStream.primitivesNeeded; data->PrimitivesStorageNeeded = queryData[0].xfbStream.primitivesNeeded;
} return S_OK; } return S_OK;
case D3D11_QUERY_SO_OVERFLOW_PREDICATE: case D3D11_QUERY_SO_OVERFLOW_PREDICATE:
@ -298,8 +298,8 @@ namespace dxvk {
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3: { case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3: {
auto data = static_cast<BOOL*>(pData); auto data = static_cast<BOOL*>(pData);
*data = queryData.xfbStream.primitivesNeeded *data = queryData[0].xfbStream.primitivesNeeded
> queryData.xfbStream.primitivesWritten; > queryData[0].xfbStream.primitivesWritten;
} return S_OK; } return S_OK;
default: default:
@ -321,7 +321,7 @@ namespace dxvk {
if (unlikely(!m_predicate.defined())) { if (unlikely(!m_predicate.defined())) {
m_predicate = m_device->AllocPredicateSlice(); m_predicate = m_device->AllocPredicateSlice();
ctx->writePredicate(m_predicate, m_query); ctx->writePredicate(m_predicate, m_query[0]);
} }
return m_predicate; return m_predicate;

View File

@ -16,7 +16,8 @@ namespace dxvk {
}; };
class D3D11Query : public D3D11DeviceChild<ID3D11Predicate> { class D3D11Query : public D3D11DeviceChild<ID3D11Predicate> {
constexpr static uint32_t MaxGpuQueries = 2;
constexpr static uint32_t MaxGpuEvents = 1;
public: public:
D3D11Query( D3D11Query(
@ -75,8 +76,8 @@ namespace dxvk {
D3D11_VK_QUERY_STATE m_state; D3D11_VK_QUERY_STATE m_state;
Rc<DxvkGpuQuery> m_query = nullptr; std::array<Rc<DxvkGpuQuery>, MaxGpuQueries> m_query;
Rc<DxvkGpuEvent> m_event = nullptr; std::array<Rc<DxvkGpuEvent>, MaxGpuEvents> m_event;
sync::Spinlock m_predicateLock; sync::Spinlock m_predicateLock;
DxvkBufferSlice m_predicate; DxvkBufferSlice m_predicate;