2019-12-16 04:28:01 +01:00
|
|
|
#include "d3d9_common_buffer.h"
|
|
|
|
|
|
|
|
#include "d3d9_device.h"
|
|
|
|
#include "d3d9_util.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
D3D9CommonBuffer::D3D9CommonBuffer(
|
|
|
|
D3D9DeviceEx* pDevice,
|
|
|
|
const D3D9_BUFFER_DESC* pDesc)
|
|
|
|
: m_parent ( pDevice ), m_desc ( *pDesc ) {
|
|
|
|
m_buffer = CreateBuffer();
|
|
|
|
if (GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_BUFFER)
|
|
|
|
m_stagingBuffer = CreateStagingBuffer();
|
|
|
|
|
|
|
|
m_sliceHandle = GetMapBuffer()->getSliceHandle();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D9CommonBuffer::Lock(
|
|
|
|
UINT OffsetToLock,
|
|
|
|
UINT SizeToLock,
|
|
|
|
void** ppbData,
|
|
|
|
DWORD Flags) {
|
|
|
|
return m_parent->LockBuffer(
|
|
|
|
this,
|
|
|
|
OffsetToLock,
|
|
|
|
SizeToLock,
|
|
|
|
ppbData,
|
|
|
|
Flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D9CommonBuffer::Unlock() {
|
|
|
|
return m_parent->UnlockBuffer(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D9CommonBuffer::GetDesc(
|
|
|
|
D3D9_BUFFER_DESC* pDesc) {
|
|
|
|
*pDesc = m_desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D9CommonBuffer::ValidateBufferProperties(const D3D9_BUFFER_DESC* pDesc) {
|
|
|
|
if (pDesc->Size == 0)
|
|
|
|
return D3DERR_INVALIDCALL;
|
|
|
|
|
|
|
|
return D3D_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-06-06 21:10:22 +02:00
|
|
|
void D3D9CommonBuffer::PreLoad() {
|
|
|
|
if (IsPoolManaged(m_desc.Pool)) {
|
|
|
|
auto lock = m_parent->LockDevice();
|
|
|
|
|
|
|
|
if (NeedsUpload())
|
|
|
|
m_parent->FlushBuffer(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-16 04:28:01 +01:00
|
|
|
Rc<DxvkBuffer> D3D9CommonBuffer::CreateBuffer() const {
|
|
|
|
DxvkBufferCreateInfo info;
|
|
|
|
info.size = m_desc.Size;
|
|
|
|
info.usage = 0;
|
|
|
|
info.stages = 0;
|
|
|
|
info.access = 0;
|
|
|
|
|
|
|
|
VkMemoryPropertyFlags memoryFlags = 0;
|
|
|
|
|
|
|
|
if (m_desc.Type == D3DRTYPE_VERTEXBUFFER) {
|
|
|
|
info.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
|
|
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
|
|
|
info.access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
|
|
|
|
|
|
|
if (m_parent->SupportsSWVP()) {
|
|
|
|
info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
|
|
|
info.stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
|
|
|
info.access |= VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_desc.Type == D3DRTYPE_INDEXBUFFER) {
|
|
|
|
info.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
|
|
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
|
|
|
info.access |= VK_ACCESS_INDEX_READ_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_DIRECT) {
|
|
|
|
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
|
|
|
|
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
|
|
|
|
|
|
|
if (!(m_desc.Usage & D3DUSAGE_WRITEONLY))
|
|
|
|
info.access |= VK_ACCESS_HOST_READ_BIT;
|
2020-07-13 17:59:01 +02:00
|
|
|
|
2019-12-16 04:28:01 +01:00
|
|
|
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
2020-07-13 17:59:01 +02:00
|
|
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
|
|
|
|
|
|
if (m_desc.Size <= DeviceLocalThreshold)
|
|
|
|
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
2019-12-16 04:28:01 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
info.stages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
|
|
info.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
|
|
|
info.access |= VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
|
|
|
|
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_parent->GetDXVKDevice()->createBuffer(info, memoryFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rc<DxvkBuffer> D3D9CommonBuffer::CreateStagingBuffer() const {
|
|
|
|
DxvkBufferCreateInfo info;
|
|
|
|
info.size = m_desc.Size;
|
|
|
|
info.stages = VK_PIPELINE_STAGE_HOST_BIT
|
|
|
|
| VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
|
|
|
|
|
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
|
|
|
|
|
|
info.access = VK_ACCESS_HOST_WRITE_BIT
|
|
|
|
| VK_ACCESS_TRANSFER_READ_BIT;
|
|
|
|
|
|
|
|
if (!(m_desc.Usage & D3DUSAGE_WRITEONLY))
|
|
|
|
info.access |= VK_ACCESS_HOST_READ_BIT;
|
|
|
|
|
|
|
|
VkMemoryPropertyFlags memoryFlags =
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
|
|
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
|
|
|
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
|
|
|
|
|
|
|
return m_parent->GetDXVKDevice()->createBuffer(info, memoryFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|