[d3d11] Refactoring resource creation (1/2) - buffers

This commit is contained in:
Philip Rebohle 2017-12-14 15:59:55 +01:00
parent 40241e0b22
commit 6de6421dfd
6 changed files with 139 additions and 147 deletions

View File

@ -7,12 +7,10 @@
namespace dxvk {
D3D11Buffer::D3D11Buffer(
D3D11Device* device,
IDXGIBufferResourcePrivate* resource,
const D3D11_BUFFER_DESC& desc)
: m_device (device),
m_resource(resource),
m_desc (desc) {
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc)
: m_device (pDevice),
m_desc (*pDesc) {
}
@ -28,10 +26,6 @@ namespace dxvk {
COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource);
COM_QUERY_IFACE(riid, ppvObject, ID3D11Buffer);
if (riid == __uuidof(IDXGIResource)
|| riid == __uuidof(IDXGIBufferResourcePrivate))
return m_resource->QueryInterface(riid, ppvObject);
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
return E_NOINTERFACE;
}
@ -43,14 +37,13 @@ namespace dxvk {
UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
UINT EvictionPriority = DXGI_RESOURCE_PRIORITY_NORMAL;
m_resource->GetEvictionPriority(&EvictionPriority);
return EvictionPriority;
Logger::warn("D3D11Buffer::GetEvictionPriority: Stub");
return DXGI_RESOURCE_PRIORITY_NORMAL;
}
void STDMETHODCALLTYPE D3D11Buffer::SetEvictionPriority(UINT EvictionPriority) {
m_resource->SetEvictionPriority(EvictionPriority);
Logger::warn("D3D11Buffer::SetEvictionPriority: Stub");
}
@ -130,7 +123,76 @@ namespace dxvk {
Rc<DxvkBuffer> D3D11Buffer::GetDXVKBuffer() {
return m_resource->GetDXVKBuffer();
return m_buffer;
}
Rc<DxvkBuffer> D3D11Buffer::CreateBuffer(
const D3D11_BUFFER_DESC* pDesc) const {
// Gather usage information
DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_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_BUFFER_BIT
| 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)
throw DxvkError("D3D11Device::CreateBuffer: D3D11_BIND_STREAM_OUTPUT not supported");
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| 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, GetMemoryFlagsForUsage(pDesc->Usage));
}
}

View File

@ -16,9 +16,8 @@ namespace dxvk {
public:
D3D11Buffer(
D3D11Device* device,
IDXGIBufferResourcePrivate* resource,
const D3D11_BUFFER_DESC& desc);
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc);
~D3D11Buffer();
HRESULT STDMETHODCALLTYPE QueryInterface(
@ -52,9 +51,13 @@ namespace dxvk {
private:
Com<D3D11Device> m_device;
Com<IDXGIBufferResourcePrivate> m_resource;
D3D11_BUFFER_DESC m_desc;
Rc<DxvkBuffer> m_buffer;
Rc<DxvkBuffer> CreateBuffer(
const D3D11_BUFFER_DESC* pDesc) const;
};
}

View File

@ -67,86 +67,12 @@ namespace dxvk {
const D3D11_BUFFER_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Buffer** ppBuffer) {
// Gather usage information
DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_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 |= GetEnabledShaderStages();
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
info.stages |= 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");
return E_INVALIDARG;
}
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| 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;
}
if (ppBuffer != nullptr) {
Com<IDXGIBufferResourcePrivate> buffer;
const Com<D3D11Buffer> buffer
= new D3D11Buffer(this, pDesc);
HRESULT hr = DXGICreateBufferResourcePrivate(
m_dxgiDevice.ptr(), &info,
GetMemoryFlagsForUsage(pDesc->Usage), 0,
&buffer);
if (FAILED(hr))
return hr;
*ppBuffer = ref(new D3D11Buffer(
this, buffer.ptr(), *pDesc));
InitBuffer(buffer.ptr(), pInitialData);
this->InitBuffer(buffer.ptr(), pInitialData);
*ppBuffer = buffer.ref();
}
return S_OK;
@ -1110,6 +1036,24 @@ namespace dxvk {
}
VkPipelineStageFlags D3D11Device::GetEnabledShaderStages() const {
VkPipelineStageFlags enabledShaderPipelineStages
= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
| VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
if (m_dxvkDevice->features().geometryShader)
enabledShaderPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
if (m_dxvkDevice->features().tessellationShader) {
enabledShaderPipelineStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
}
return enabledShaderPipelineStages;
}
bool D3D11Device::CheckFeatureLevelSupport(
const Rc<DxvkAdapter>& adapter,
D3D_FEATURE_LEVEL featureLevel) {
@ -1201,7 +1145,7 @@ namespace dxvk {
void D3D11Device::InitBuffer(
IDXGIBufferResourcePrivate* pBuffer,
D3D11Buffer* pBuffer,
const D3D11_SUBRESOURCE_DATA* pInitialData) {
const Rc<DxvkBuffer> buffer = pBuffer->GetDXVKBuffer();
@ -1427,49 +1371,6 @@ namespace dxvk {
}
VkPipelineStageFlags D3D11Device::GetEnabledShaderStages() const {
VkPipelineStageFlags enabledShaderPipelineStages
= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
| VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
if (m_dxvkDevice->features().geometryShader)
enabledShaderPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
if (m_dxvkDevice->features().tessellationShader) {
enabledShaderPipelineStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
}
return enabledShaderPipelineStages;
}
VkMemoryPropertyFlags D3D11Device::GetMemoryFlagsForUsage(D3D11_USAGE usage) const {
VkMemoryPropertyFlags memoryFlags = 0;
switch (usage) {
case D3D11_USAGE_DEFAULT:
case D3D11_USAGE_IMMUTABLE:
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
break;
case D3D11_USAGE_DYNAMIC:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
break;
case D3D11_USAGE_STAGING:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
break;
}
return memoryFlags;
}
VkSamplerAddressMode D3D11Device::DecodeAddressMode(
D3D11_TEXTURE_ADDRESS_MODE mode) const {
switch (mode) {

View File

@ -11,6 +11,8 @@
namespace dxvk {
class DxgiAdapter;
class D3D11Buffer;
class D3D11DeviceContext;
class D3D11PresentDevice;
class D3D11ShaderModule;
@ -222,6 +224,8 @@ namespace dxvk {
return m_dxvkDevice;
}
VkPipelineStageFlags GetEnabledShaderStages() const;
static bool CheckFeatureLevelSupport(
const Rc<DxvkAdapter>& adapter,
D3D_FEATURE_LEVEL featureLevel);
@ -258,7 +262,7 @@ namespace dxvk {
ID3D11ClassLinkage* pClassLinkage);
void InitBuffer(
IDXGIBufferResourcePrivate* pBuffer,
D3D11Buffer* pBuffer,
const D3D11_SUBRESOURCE_DATA* pInitialData);
void InitTexture(
@ -285,11 +289,6 @@ namespace dxvk {
UINT Count,
VkSampleCountFlagBits* pCount) const;
VkPipelineStageFlags GetEnabledShaderStages() const;
VkMemoryPropertyFlags GetMemoryFlagsForUsage(
D3D11_USAGE usage) const;
VkSamplerAddressMode DecodeAddressMode(
D3D11_TEXTURE_ADDRESS_MODE mode) const;

View File

@ -35,4 +35,29 @@ namespace dxvk {
}
}
VkMemoryPropertyFlags GetMemoryFlagsForUsage(D3D11_USAGE usage) {
VkMemoryPropertyFlags memoryFlags = 0;
switch (usage) {
case D3D11_USAGE_DEFAULT:
case D3D11_USAGE_IMMUTABLE:
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
break;
case D3D11_USAGE_DYNAMIC:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
break;
case D3D11_USAGE_STAGING:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
break;
}
return memoryFlags;
}
}

View File

@ -9,5 +9,7 @@ namespace dxvk {
VkCompareOp DecodeCompareOp(
D3D11_COMPARISON_FUNC mode);
VkMemoryPropertyFlags GetMemoryFlagsForUsage(
D3D11_USAGE usage);
}