mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 09:23:53 +01:00
fb3734ce49
With this patch The Witcher 3 can successfully load saved game.
145 lines
4.6 KiB
C++
145 lines
4.6 KiB
C++
#include "d3d11_buffer.h"
|
|
#include "d3d11_context.h"
|
|
#include "d3d11_device.h"
|
|
|
|
#include "../dxvk/dxvk_data.h"
|
|
|
|
namespace dxvk {
|
|
|
|
D3D11Buffer::D3D11Buffer(
|
|
D3D11Device* pDevice,
|
|
const D3D11_BUFFER_DESC* pDesc)
|
|
: m_device (pDevice),
|
|
m_desc (*pDesc),
|
|
m_buffer (CreateBuffer(pDesc)),
|
|
m_bufferInfo{ m_buffer->slice() } {
|
|
|
|
}
|
|
|
|
|
|
D3D11Buffer::~D3D11Buffer() {
|
|
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11Buffer::QueryInterface(REFIID riid, void** ppvObject) {
|
|
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource);
|
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11Buffer);
|
|
|
|
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Buffer::GetDevice(ID3D11Device** ppDevice) {
|
|
*ppDevice = m_device.ref();
|
|
}
|
|
|
|
|
|
UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
|
|
Logger::warn("D3D11Buffer::GetEvictionPriority: Stub");
|
|
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Buffer::SetEvictionPriority(UINT EvictionPriority) {
|
|
Logger::warn("D3D11Buffer::SetEvictionPriority: Stub");
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Buffer::GetType(D3D11_RESOURCE_DIMENSION* pResourceDimension) {
|
|
*pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER;
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Buffer::GetDesc(D3D11_BUFFER_DESC* pDesc) {
|
|
*pDesc = m_desc;
|
|
}
|
|
|
|
|
|
Rc<DxvkBuffer> D3D11Buffer::CreateBuffer(
|
|
const D3D11_BUFFER_DESC* pDesc) const {
|
|
DxvkBufferCreateInfo info;
|
|
info.size = pDesc->ByteWidth;
|
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
|
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
info.access = VK_ACCESS_TRANSFER_READ_BIT
|
|
| VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
if (pDesc->BindFlags & D3D11_BIND_VERTEX_BUFFER) {
|
|
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 (pDesc->BindFlags & D3D11_BIND_INDEX_BUFFER) {
|
|
info.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
|
info.access |= VK_ACCESS_INDEX_READ_BIT;
|
|
}
|
|
|
|
if (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) {
|
|
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
|
info.stages |= m_device->GetEnabledShaderStages();
|
|
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
|
|
}
|
|
|
|
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
|
|
info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
|
info.stages |= m_device->GetEnabledShaderStages();
|
|
info.access |= VK_ACCESS_SHADER_READ_BIT;
|
|
}
|
|
|
|
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) {
|
|
Logger::err("D3D11Device::CreateBuffer: D3D11_BIND_STREAM_OUTPUT not supported");
|
|
}
|
|
|
|
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
|
|
info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
|
info.stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
|
| VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
info.access |= VK_ACCESS_SHADER_READ_BIT
|
|
| VK_ACCESS_SHADER_WRITE_BIT;
|
|
}
|
|
|
|
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) {
|
|
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
|
|
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
|
}
|
|
|
|
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
|
|
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
|
|
info.access |= VK_ACCESS_HOST_READ_BIT;
|
|
}
|
|
|
|
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) {
|
|
info.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
|
|
info.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
|
info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
|
}
|
|
|
|
return m_device->GetDXVKDevice()->createBuffer(
|
|
info, GetMemoryFlags(pDesc));
|
|
}
|
|
|
|
|
|
VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags(
|
|
const D3D11_BUFFER_DESC* pDesc) const {
|
|
// Default constant buffers may get updated frequently with calls
|
|
// to D3D11DeviceContext::UpdateSubresource, so we'll map them to
|
|
// host memory in order to allow direct access to the buffer
|
|
if ((pDesc->Usage == D3D11_USAGE_DEFAULT)
|
|
&& (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)) {
|
|
return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
}
|
|
|
|
// Use default memory flags for the intended use
|
|
return GetMemoryFlagsForUsage(pDesc->Usage);
|
|
}
|
|
|
|
}
|