1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-22 07:54:15 +01:00

[d3d9] Refactor AllocUpBuffer so it can be used for managed uploads

This commit is contained in:
Robin Kertels 2021-04-02 01:20:30 +02:00 committed by Joshie
parent 8cc0c9a0f1
commit bb11d7dee8
2 changed files with 53 additions and 33 deletions

View File

@ -2375,7 +2375,7 @@ namespace dxvk {
const uint32_t upSize = drawInfo.vertexCount * VertexStreamZeroStride; const uint32_t upSize = drawInfo.vertexCount * VertexStreamZeroStride;
auto upSlice = AllocUpBuffer(upSize); auto upSlice = AllocTempBuffer<true>(upSize);
std::memcpy(upSlice.mapPtr, pVertexStreamZeroData, upSize); std::memcpy(upSlice.mapPtr, pVertexStreamZeroData, upSize);
EmitCs([this, EmitCs([this,
@ -2426,7 +2426,7 @@ namespace dxvk {
const uint32_t upSize = vertexSize + indicesSize; const uint32_t upSize = vertexSize + indicesSize;
auto upSlice = AllocUpBuffer(upSize); auto upSlice = AllocTempBuffer<true>(upSize);
uint8_t* data = reinterpret_cast<uint8_t*>(upSlice.mapPtr); uint8_t* data = reinterpret_cast<uint8_t*>(upSlice.mapPtr);
std::memcpy(data, pVertexStreamZeroData, vertexSize); std::memcpy(data, pVertexStreamZeroData, vertexSize);
@ -3800,58 +3800,76 @@ namespace dxvk {
} }
D3D9UPBufferSlice D3D9DeviceEx::AllocUpBuffer(VkDeviceSize size) { template<bool UpBuffer>
D3D9BufferSlice D3D9DeviceEx::AllocTempBuffer(VkDeviceSize size) {
constexpr VkDeviceSize DefaultSize = 1 << 20; constexpr VkDeviceSize DefaultSize = 1 << 20;
constexpr VkMemoryPropertyFlags memoryFlags VkMemoryPropertyFlags memoryFlags
= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
if constexpr (UpBuffer) {
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
D3D9BufferSlice& currentSlice = UpBuffer ? m_upBuffer : m_managedUploadBuffer;
if (size <= DefaultSize) { if (size <= DefaultSize) {
if (unlikely(!m_upBuffer.slice.defined())) { if (unlikely(!currentSlice.slice.defined())) {
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = DefaultSize; info.size = DefaultSize;
if constexpr (UpBuffer) {
info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT; | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
| VK_ACCESS_INDEX_READ_BIT; | VK_ACCESS_INDEX_READ_BIT;
info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
} else {
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT;
}
m_upBuffer.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); currentSlice.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags));
m_upBuffer.mapPtr = m_upBuffer.slice.mapPtr(0); currentSlice.mapPtr = currentSlice.slice.mapPtr(0);
} else if (unlikely(m_upBuffer.slice.length() < size)) { } else if (unlikely(currentSlice.slice.length() < size)) {
auto physSlice = m_upBuffer.slice.buffer()->allocSlice(); auto physSlice = currentSlice.slice.buffer()->allocSlice();
m_upBuffer.slice = DxvkBufferSlice(m_upBuffer.slice.buffer()); currentSlice.slice = DxvkBufferSlice(currentSlice.slice.buffer());
m_upBuffer.mapPtr = physSlice.mapPtr; currentSlice.mapPtr = physSlice.mapPtr;
EmitCs([ EmitCs([
cBuffer = m_upBuffer.slice.buffer(), cBuffer = currentSlice.slice.buffer(),
cSlice = physSlice cSlice = physSlice
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice); ctx->invalidateBuffer(cBuffer, cSlice);
}); });
} }
D3D9UPBufferSlice result; D3D9BufferSlice result;
result.slice = m_upBuffer.slice.subSlice(0, size); result.slice = currentSlice.slice.subSlice(0, size);
result.mapPtr = reinterpret_cast<char*>(m_upBuffer.mapPtr) + m_upBuffer.slice.offset(); result.mapPtr = reinterpret_cast<char*>(currentSlice.mapPtr) + currentSlice.slice.offset();
VkDeviceSize adjust = align(size, CACHE_LINE_SIZE); VkDeviceSize adjust = align(size, CACHE_LINE_SIZE);
m_upBuffer.slice = m_upBuffer.slice.subSlice(adjust, m_upBuffer.slice.length() - adjust); currentSlice.slice = currentSlice.slice.subSlice(adjust, currentSlice.slice.length() - adjust);
return result; return result;
} else { } else {
// Create a temporary buffer for very large allocations // Create a temporary buffer for very large allocations
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = size; info.size = size;
if constexpr (UpBuffer) {
info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT; | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
| VK_ACCESS_INDEX_READ_BIT; | VK_ACCESS_INDEX_READ_BIT;
info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
} else {
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT;
}
D3D9UPBufferSlice result; D3D9BufferSlice result;
result.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); result.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags));
result.mapPtr = result.slice.mapPtr(0); result.mapPtr = result.slice.mapPtr(0);
return result; return result;

View File

@ -85,7 +85,7 @@ namespace dxvk {
Rc<DxvkSampler> depth; Rc<DxvkSampler> depth;
}; };
struct D3D9UPBufferSlice { struct D3D9BufferSlice {
DxvkBufferSlice slice = {}; DxvkBufferSlice slice = {};
void* mapPtr = nullptr; void* mapPtr = nullptr;
}; };
@ -999,7 +999,8 @@ namespace dxvk {
Rc<DxvkBuffer> m_psFixedFunction; Rc<DxvkBuffer> m_psFixedFunction;
Rc<DxvkBuffer> m_psShared; Rc<DxvkBuffer> m_psShared;
D3D9UPBufferSlice m_upBuffer; D3D9BufferSlice m_upBuffer;
D3D9BufferSlice m_managedUploadBuffer;
const D3D9Options m_d3d9Options; const D3D9Options m_d3d9Options;
DxsoOptions m_dxsoOptions; DxsoOptions m_dxsoOptions;
@ -1073,7 +1074,8 @@ namespace dxvk {
void DetermineConstantLayouts(bool canSWVP); void DetermineConstantLayouts(bool canSWVP);
D3D9UPBufferSlice AllocUpBuffer(VkDeviceSize size); template<bool UpBuffer>
D3D9BufferSlice AllocTempBuffer(VkDeviceSize size);
bool ShouldRecord(); bool ShouldRecord();