2017-12-16 18:10:55 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
|
|
|
|
2018-07-16 18:45:54 +02:00
|
|
|
#include "../util/thread.h"
|
2017-12-16 18:10:55 +01:00
|
|
|
#include "dxvk_cmdlist.h"
|
|
|
|
#include "dxvk_sync.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
class DxvkDevice;
|
2018-09-20 08:01:30 +02:00
|
|
|
|
|
|
|
struct DxvkSubmission {
|
|
|
|
Rc<DxvkCommandList> cmdList;
|
|
|
|
Rc<DxvkSemaphore> semWait;
|
|
|
|
Rc<DxvkSemaphore> semWake;
|
|
|
|
};
|
2017-12-16 18:10:55 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Submission queue
|
|
|
|
*/
|
|
|
|
class DxvkSubmissionQueue {
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
DxvkSubmissionQueue(DxvkDevice* device);
|
|
|
|
~DxvkSubmissionQueue();
|
2018-06-04 23:24:42 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Number of pending submissions
|
|
|
|
*
|
|
|
|
* A return value of 0 indicates
|
|
|
|
* that the GPU is currently idle.
|
|
|
|
* \returns Pending submission count
|
|
|
|
*/
|
|
|
|
uint32_t pendingSubmissions() const {
|
|
|
|
return m_submits.load();
|
|
|
|
}
|
2017-12-16 18:10:55 +01:00
|
|
|
|
2018-06-04 23:24:42 +02:00
|
|
|
/**
|
|
|
|
* \brief Submits a command list
|
|
|
|
*
|
|
|
|
* Submits a command list to the queue thread.
|
|
|
|
* This thread will wait for the command list
|
|
|
|
* to finish executing on the GPU and signal
|
|
|
|
* any queries and events that are used by
|
|
|
|
* the command list in question.
|
2018-09-20 08:01:30 +02:00
|
|
|
* \param [in] submission Command submission
|
|
|
|
*/
|
|
|
|
void submit(DxvkSubmission submission);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Synchronizes with submission thread
|
|
|
|
*
|
|
|
|
* Waits until all submissions queued prior
|
|
|
|
* to this call are submitted to the GPU.
|
|
|
|
*/
|
|
|
|
void synchronize();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Locks external queue lock
|
|
|
|
* Protects the Vulkan queue.
|
|
|
|
*/
|
|
|
|
void lock() {
|
|
|
|
m_externalLock.lock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Locks external queue lock
|
|
|
|
* Releases the Vulkan queue.
|
2018-06-04 23:24:42 +02:00
|
|
|
*/
|
2018-09-20 08:01:30 +02:00
|
|
|
void unlock() {
|
|
|
|
m_externalLock.unlock();
|
|
|
|
}
|
2017-12-16 18:10:55 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
DxvkDevice* m_device;
|
|
|
|
|
|
|
|
std::atomic<bool> m_stopped = { false };
|
2018-06-04 23:24:42 +02:00
|
|
|
std::atomic<uint32_t> m_submits = { 0u };
|
2018-09-20 08:01:30 +02:00
|
|
|
|
|
|
|
std::mutex m_externalLock;
|
|
|
|
|
|
|
|
std::mutex m_queueLock;
|
|
|
|
std::condition_variable m_queueCond;
|
|
|
|
std::queue<Rc<DxvkCommandList>> m_queueEntries;
|
|
|
|
dxvk::thread m_queueThread;
|
2017-12-16 18:10:55 +01:00
|
|
|
|
2018-09-20 08:01:30 +02:00
|
|
|
std::mutex m_submitLock;
|
|
|
|
std::condition_variable m_submitCondOnAdd;
|
|
|
|
std::condition_variable m_submitCondOnTake;
|
|
|
|
std::queue<DxvkSubmission> m_submitQueue;
|
|
|
|
dxvk::thread m_submitThread;
|
2017-12-16 18:10:55 +01:00
|
|
|
|
2018-09-20 08:01:30 +02:00
|
|
|
void threadSubmit();
|
|
|
|
void threadQueue();
|
2017-12-16 18:10:55 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2018-07-16 18:45:54 +02:00
|
|
|
}
|