mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 19:02:55 +02:00
Fix transfer buffering
This commit is contained in:
parent
285222d490
commit
eafe0a04d5
2 changed files with 34 additions and 30 deletions
|
@ -108,16 +108,10 @@ public:
|
||||||
using VoidLambdaQueue = std::queue<VoidLambda>;
|
using VoidLambdaQueue = std::queue<VoidLambda>;
|
||||||
using ThreadPointer = std::shared_ptr<std::thread>;
|
using ThreadPointer = std::shared_ptr<std::thread>;
|
||||||
const GL45VariableAllocationTexture& _parent;
|
const GL45VariableAllocationTexture& _parent;
|
||||||
const uint16_t _sourceMip;
|
|
||||||
const uint16_t _targetMip;
|
|
||||||
const uint8_t _face;
|
|
||||||
const uint32_t _lines;
|
|
||||||
const uint32_t _lineOffset;
|
|
||||||
// Holds the contents to transfer to the GPU in CPU memory
|
// Holds the contents to transfer to the GPU in CPU memory
|
||||||
std::vector<uint8_t> _buffer;
|
std::vector<uint8_t> _buffer;
|
||||||
// Indicates if a transfer from backing storage to interal storage has started
|
// Indicates if a transfer from backing storage to interal storage has started
|
||||||
bool _bufferingStarted { false };
|
bool _bufferingStarted { false };
|
||||||
bool _transferOnly { false };
|
|
||||||
bool _bufferingCompleted { false };
|
bool _bufferingCompleted { false };
|
||||||
VoidLambda _transferLambda;
|
VoidLambda _transferLambda;
|
||||||
VoidLambda _bufferingLambda;
|
VoidLambda _bufferingLambda;
|
||||||
|
@ -128,6 +122,7 @@ public:
|
||||||
static void bufferLoop();
|
static void bufferLoop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TransferJob(const TransferJob& other) = delete;
|
||||||
TransferJob(const GL45VariableAllocationTexture& parent, std::function<void()> transferLambda);
|
TransferJob(const GL45VariableAllocationTexture& parent, std::function<void()> transferLambda);
|
||||||
TransferJob(const GL45VariableAllocationTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines = 0, uint32_t lineOffset = 0);
|
TransferJob(const GL45VariableAllocationTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines = 0, uint32_t lineOffset = 0);
|
||||||
bool tryTransfer();
|
bool tryTransfer();
|
||||||
|
@ -139,7 +134,7 @@ public:
|
||||||
void transfer();
|
void transfer();
|
||||||
};
|
};
|
||||||
|
|
||||||
using TransferQueue = std::queue<TransferJob>;
|
using TransferQueue = std::queue<std::unique_ptr<TransferJob>>;
|
||||||
static MemoryPressureState _memoryPressureState;
|
static MemoryPressureState _memoryPressureState;
|
||||||
protected:
|
protected:
|
||||||
static std::atomic<bool> _memoryPressureStateStale;
|
static std::atomic<bool> _memoryPressureStateStale;
|
||||||
|
|
|
@ -78,11 +78,18 @@ void TransferJob::stopTransferLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines, uint32_t lineOffset)
|
TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines, uint32_t lineOffset)
|
||||||
: _parent(parent), _sourceMip(sourceMip), _targetMip(targetMip), _face(face), _lines(lines), _lineOffset(lineOffset) {
|
: _parent(parent) {
|
||||||
|
|
||||||
|
auto transferDimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
|
||||||
|
GLenum format;
|
||||||
|
GLenum type;
|
||||||
|
auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face);
|
||||||
|
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), mipData->getFormat());
|
||||||
|
format = texelFormat.format;
|
||||||
|
type = texelFormat.type;
|
||||||
|
|
||||||
if (0 == lines) {
|
if (0 == lines) {
|
||||||
_bufferingLambda = [this] {
|
_bufferingLambda = [=] {
|
||||||
auto mipData = _parent._gpuObject.accessStoredMipFace(_sourceMip, _face);
|
|
||||||
auto size = mipData->getSize();
|
auto size = mipData->getSize();
|
||||||
_buffer.resize(size);
|
_buffer.resize(size);
|
||||||
memcpy(&_buffer[0], mipData->readData(), size);
|
memcpy(&_buffer[0], mipData->readData(), size);
|
||||||
|
@ -90,38 +97,39 @@ TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t s
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_bufferingLambda = [this] {
|
transferDimensions.y = lines;
|
||||||
auto mipData = _parent._gpuObject.accessStoredMipFace(_sourceMip, _face);
|
_bufferingLambda = [=] {
|
||||||
auto dimensions = _parent._gpuObject.evalMipDimensions(_sourceMip);
|
auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
|
||||||
auto mipSize = mipData->getSize();
|
auto mipSize = mipData->getSize();
|
||||||
auto bytesPerLine = (uint32_t)mipSize / dimensions.y;
|
auto bytesPerLine = (uint32_t)mipSize / dimensions.y;
|
||||||
auto transferSize = bytesPerLine * _lines;
|
auto transferSize = bytesPerLine * lines;
|
||||||
auto sourceOffset = bytesPerLine * _lineOffset;
|
auto sourceOffset = bytesPerLine * lineOffset;
|
||||||
_buffer.resize(transferSize);
|
_buffer.resize(transferSize);
|
||||||
memcpy(&_buffer[0], mipData->readData() + sourceOffset, transferSize);
|
memcpy(&_buffer[0], mipData->readData() + sourceOffset, transferSize);
|
||||||
_bufferingCompleted = true;
|
_bufferingCompleted = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_transferLambda = [this] {
|
_transferLambda = [=] {
|
||||||
auto mipData = _parent._gpuObject.accessStoredMipFace(_sourceMip, _face);
|
_parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, format, type, _buffer.data());
|
||||||
auto dimensions = _parent._gpuObject.evalMipDimensions(_sourceMip);
|
|
||||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), mipData->getFormat());
|
|
||||||
_parent.copyMipFaceLinesFromTexture(_targetMip, _face, dimensions, _lineOffset, texelFormat.format, texelFormat.type, &_buffer[0]);
|
|
||||||
_buffer.swap(std::vector<uint8_t>());
|
_buffer.swap(std::vector<uint8_t>());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, std::function<void()> transferLambda)
|
TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, std::function<void()> transferLambda)
|
||||||
: _parent(parent), _sourceMip(0), _targetMip(0), _face(0), _lines(0), _lineOffset(0), _bufferingCompleted(true), _transferLambda(transferLambda) {
|
: _parent(parent), _bufferingCompleted(true), _transferLambda(transferLambda) {
|
||||||
if (!_bufferThread) {
|
|
||||||
_bufferThread = std::make_shared<std::thread>([] {
|
|
||||||
TransferJob::bufferLoop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransferJob::tryTransfer() {
|
bool TransferJob::tryTransfer() {
|
||||||
|
// Disable threaded texture transfer for now
|
||||||
|
#if 1
|
||||||
|
if (!_bufferingCompleted) {
|
||||||
|
_bufferingLambda();
|
||||||
|
_bufferingCompleted = true;
|
||||||
|
}
|
||||||
|
_transferLambda();
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
// Are we ready to transfer
|
// Are we ready to transfer
|
||||||
if (_bufferingCompleted) {
|
if (_bufferingCompleted) {
|
||||||
_transferLambda();
|
_transferLambda();
|
||||||
|
@ -130,6 +138,7 @@ bool TransferJob::tryTransfer() {
|
||||||
|
|
||||||
startBuffering();
|
startBuffering();
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferJob::startBuffering() {
|
void TransferJob::startBuffering() {
|
||||||
|
@ -391,7 +400,7 @@ void GL45VariableAllocationTexture::executeNextTransfer(const TexturePointer& cu
|
||||||
if (!_pendingTransfers.empty()) {
|
if (!_pendingTransfers.empty()) {
|
||||||
// Keeping hold of a strong pointer during the transfer ensures that the transfer thread cannot try to access a destroyed texture
|
// Keeping hold of a strong pointer during the transfer ensures that the transfer thread cannot try to access a destroyed texture
|
||||||
_currentTransferTexture = currentTexture;
|
_currentTransferTexture = currentTexture;
|
||||||
if (_pendingTransfers.front().tryTransfer()) {
|
if (_pendingTransfers.front()->tryTransfer()) {
|
||||||
_pendingTransfers.pop();
|
_pendingTransfers.pop();
|
||||||
_currentTransferTexture.reset();
|
_currentTransferTexture.reset();
|
||||||
}
|
}
|
||||||
|
@ -542,7 +551,7 @@ void GL45ResourceTexture::populateTransferQueue() {
|
||||||
// If the mip is less than the max transfer size, then just do it in one transfer
|
// If the mip is less than the max transfer size, then just do it in one transfer
|
||||||
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
|
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
|
||||||
// Can the mip be transferred in one go
|
// Can the mip be transferred in one go
|
||||||
_pendingTransfers.emplace(*this, sourceMip, targetMip, face);
|
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,13 +565,13 @@ void GL45ResourceTexture::populateTransferQueue() {
|
||||||
uint32_t lineOffset = 0;
|
uint32_t lineOffset = 0;
|
||||||
while (lineOffset < lines) {
|
while (lineOffset < lines) {
|
||||||
uint32_t linesToCopy = std::min<uint32_t>(lines - lineOffset, linesPerTransfer);
|
uint32_t linesToCopy = std::min<uint32_t>(lines - lineOffset, linesPerTransfer);
|
||||||
_pendingTransfers.emplace(TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
|
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
|
||||||
lineOffset += linesToCopy;
|
lineOffset += linesToCopy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue up the sampler and populated mip change for after the transfer has completed
|
// queue up the sampler and populated mip change for after the transfer has completed
|
||||||
_pendingTransfers.emplace(TransferJob(*this, [=] {
|
_pendingTransfers.emplace(new TransferJob(*this, [=] {
|
||||||
_populatedMip = sourceMip;
|
_populatedMip = sourceMip;
|
||||||
syncSampler();
|
syncSampler();
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Reference in a new issue