mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[dxvk] Clean up CS chunk allocation
This also makes it more robust w.r.t. alignment.
This commit is contained in:
parent
4c8ee300b5
commit
23067c48c7
2 changed files with 54 additions and 48 deletions
|
@ -31,7 +31,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_head = nullptr;
|
m_head = nullptr;
|
||||||
m_tail = nullptr;
|
m_next = &m_head;
|
||||||
} else {
|
} else {
|
||||||
while (cmd != nullptr) {
|
while (cmd != nullptr) {
|
||||||
cmd->exec(ctx);
|
cmd->exec(ctx);
|
||||||
|
@ -51,7 +51,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_head = nullptr;
|
m_head = nullptr;
|
||||||
m_tail = nullptr;
|
m_next = &m_head;
|
||||||
|
|
||||||
m_commandOffset = 0;
|
m_commandOffset = 0;
|
||||||
}
|
}
|
||||||
|
@ -263,4 +263,4 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@ namespace dxvk {
|
||||||
* that can be recorded into a command list.
|
* that can be recorded into a command list.
|
||||||
*/
|
*/
|
||||||
class DxvkCsCmd {
|
class DxvkCsCmd {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~DxvkCsCmd() { }
|
virtual ~DxvkCsCmd() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves next command in a command chain
|
* \brief Retrieves next command in a command chain
|
||||||
*
|
*
|
||||||
* This can be used to quickly iterate
|
* This can be used to quickly iterate
|
||||||
* over commands within a chunk.
|
* over commands within a chunk.
|
||||||
* \returns Pointer the next command
|
* \returns Pointer the next command
|
||||||
|
@ -34,25 +34,27 @@ namespace dxvk {
|
||||||
DxvkCsCmd* next() const {
|
DxvkCsCmd* next() const {
|
||||||
return m_next;
|
return m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sets next command in a command chain
|
* \brief Retrieves pointer to next chain
|
||||||
* \param [in] next Next command
|
*
|
||||||
|
* Used to chain commands.
|
||||||
|
* \returns Pointer the next command
|
||||||
*/
|
*/
|
||||||
void setNext(DxvkCsCmd* next) {
|
DxvkCsCmd** chain() {
|
||||||
m_next = next;
|
return &m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Executes embedded commands
|
* \brief Executes embedded commands
|
||||||
* \param [in] ctx The target context
|
* \param [in] ctx The target context
|
||||||
*/
|
*/
|
||||||
virtual void exec(DxvkContext* ctx) = 0;
|
virtual void exec(DxvkContext* ctx) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DxvkCsCmd* m_next = nullptr;
|
DxvkCsCmd* m_next = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ namespace dxvk {
|
||||||
* used to execute an embedded command.
|
* used to execute an embedded command.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class alignas(16) DxvkCsTypedCmd : public DxvkCsCmd {
|
class DxvkCsTypedCmd : public DxvkCsCmd {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ namespace dxvk {
|
||||||
* submitting the command to a cs chunk.
|
* submitting the command to a cs chunk.
|
||||||
*/
|
*/
|
||||||
template<typename T, typename M>
|
template<typename T, typename M>
|
||||||
class alignas(16) DxvkCsDataCmd : public DxvkCsCmd {
|
class DxvkCsDataCmd : public DxvkCsCmd {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -165,21 +167,13 @@ namespace dxvk {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool push(T& command) {
|
bool push(T& command) {
|
||||||
using FuncType = DxvkCsTypedCmd<T>;
|
using FuncType = DxvkCsTypedCmd<T>;
|
||||||
|
void* ptr = alloc<FuncType>();
|
||||||
if (unlikely(m_commandOffset > MaxBlockSize - sizeof(FuncType)))
|
|
||||||
|
if (unlikely(!ptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DxvkCsCmd* tail = m_tail;
|
auto next = new (ptr) FuncType(std::move(command));
|
||||||
|
append(next);
|
||||||
m_tail = new (m_data + m_commandOffset)
|
|
||||||
FuncType(std::move(command));
|
|
||||||
|
|
||||||
if (likely(tail != nullptr))
|
|
||||||
tail->setNext(m_tail);
|
|
||||||
else
|
|
||||||
m_head = m_tail;
|
|
||||||
|
|
||||||
m_commandOffset += sizeof(FuncType);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,21 +192,15 @@ namespace dxvk {
|
||||||
template<typename M, typename T, typename... Args>
|
template<typename M, typename T, typename... Args>
|
||||||
M* pushCmd(T& command, Args&&... args) {
|
M* pushCmd(T& command, Args&&... args) {
|
||||||
using FuncType = DxvkCsDataCmd<T, M>;
|
using FuncType = DxvkCsDataCmd<T, M>;
|
||||||
|
void* ptr = alloc<FuncType>();
|
||||||
if (unlikely(m_commandOffset > MaxBlockSize - sizeof(FuncType)))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
FuncType* func = new (m_data + m_commandOffset)
|
|
||||||
FuncType(std::move(command), std::forward<Args>(args)...);
|
|
||||||
|
|
||||||
if (likely(m_tail != nullptr))
|
|
||||||
m_tail->setNext(func);
|
|
||||||
else
|
|
||||||
m_head = func;
|
|
||||||
m_tail = func;
|
|
||||||
|
|
||||||
m_commandOffset += sizeof(FuncType);
|
if (unlikely(!ptr))
|
||||||
return func->data();
|
return nullptr;
|
||||||
|
|
||||||
|
auto next = new (ptr) FuncType(std::move(command), std::forward<Args>(args)...);
|
||||||
|
append(next);
|
||||||
|
|
||||||
|
return next->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,13 +231,31 @@ namespace dxvk {
|
||||||
|
|
||||||
size_t m_commandOffset = 0;
|
size_t m_commandOffset = 0;
|
||||||
|
|
||||||
DxvkCsCmd* m_head = nullptr;
|
DxvkCsCmd* m_head = nullptr;
|
||||||
DxvkCsCmd* m_tail = nullptr;
|
DxvkCsCmd** m_next = &m_head;
|
||||||
|
|
||||||
DxvkCsChunkFlags m_flags;
|
DxvkCsChunkFlags m_flags;
|
||||||
|
|
||||||
alignas(64)
|
alignas(64)
|
||||||
char m_data[MaxBlockSize];
|
char m_data[MaxBlockSize];
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void* alloc() {
|
||||||
|
if (alignof(T) > alignof(DxvkCsCmd))
|
||||||
|
m_commandOffset = dxvk::align(m_commandOffset, alignof(T));
|
||||||
|
|
||||||
|
if (unlikely(m_commandOffset + sizeof(T) > MaxBlockSize))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
void* result = &m_data[m_commandOffset];
|
||||||
|
m_commandOffset += sizeof(T);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(DxvkCsCmd* cmd) {
|
||||||
|
*m_next = cmd;
|
||||||
|
m_next = cmd->chain();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue