mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 22:54:16 +01:00
[d3d11] Fixed buffer bindings with non-zero offsets
This commit is contained in:
parent
6de6421dfd
commit
9827ace3b0
@ -9,8 +9,9 @@ namespace dxvk {
|
|||||||
D3D11Buffer::D3D11Buffer(
|
D3D11Buffer::D3D11Buffer(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_BUFFER_DESC* pDesc)
|
const D3D11_BUFFER_DESC* pDesc)
|
||||||
: m_device (pDevice),
|
: m_device (pDevice),
|
||||||
m_desc (*pDesc) {
|
m_desc (*pDesc),
|
||||||
|
m_buffer (CreateBuffer(pDesc)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ namespace dxvk {
|
|||||||
D3D11_MAP MapType,
|
D3D11_MAP MapType,
|
||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedSubresource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedSubresource) {
|
||||||
const Rc<DxvkBuffer> buffer = GetDXVKBuffer();
|
const Rc<DxvkBuffer> buffer = m_buffer;
|
||||||
|
|
||||||
if (buffer->mapPtr(0) == nullptr) {
|
if (buffer->mapPtr(0) == nullptr) {
|
||||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||||
@ -122,8 +123,13 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> D3D11Buffer::GetDXVKBuffer() {
|
DxvkBufferSlice D3D11Buffer::GetCurrentBufferSlice() const {
|
||||||
return m_buffer;
|
return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkBufferSlice D3D11Buffer::GetInitialBufferSlice() const {
|
||||||
|
return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,8 +11,17 @@ namespace dxvk {
|
|||||||
class D3D11DeviceContext;
|
class D3D11DeviceContext;
|
||||||
|
|
||||||
|
|
||||||
class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
|
class D3D11BufferStorage {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
|
||||||
|
static constexpr VkDeviceSize BufferSliceAlignment = 64;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11Buffer(
|
D3D11Buffer(
|
||||||
@ -46,14 +55,15 @@ namespace dxvk {
|
|||||||
void Unmap(
|
void Unmap(
|
||||||
D3D11DeviceContext* pContext);
|
D3D11DeviceContext* pContext);
|
||||||
|
|
||||||
Rc<DxvkBuffer> GetDXVKBuffer();
|
DxvkBufferSlice GetCurrentBufferSlice() const;
|
||||||
|
DxvkBufferSlice GetInitialBufferSlice() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<D3D11Device> m_device;
|
const Com<D3D11Device> m_device;
|
||||||
D3D11_BUFFER_DESC m_desc;
|
const D3D11_BUFFER_DESC m_desc;
|
||||||
|
|
||||||
Rc<DxvkBuffer> m_buffer;
|
Rc<DxvkBuffer> m_buffer;
|
||||||
|
|
||||||
Rc<DxvkBuffer> CreateBuffer(
|
Rc<DxvkBuffer> CreateBuffer(
|
||||||
const D3D11_BUFFER_DESC* pDesc) const;
|
const D3D11_BUFFER_DESC* pDesc) const;
|
||||||
|
@ -395,23 +395,28 @@ namespace dxvk {
|
|||||||
pDstResource->GetType(&resourceType);
|
pDstResource->GetType(&resourceType);
|
||||||
|
|
||||||
if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
Com<IDXGIBufferResourcePrivate> bufferResource;
|
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
|
||||||
|
const auto bufferSlice = bufferResource->GetCurrentBufferSlice();
|
||||||
pDstResource->QueryInterface(
|
|
||||||
__uuidof(IDXGIBufferResourcePrivate),
|
|
||||||
reinterpret_cast<void**>(&bufferResource));
|
|
||||||
|
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
VkDeviceSize size = VK_WHOLE_SIZE;
|
VkDeviceSize size = bufferSlice.bufferRange();
|
||||||
|
|
||||||
if (pDstBox != nullptr) {
|
if (pDstBox != nullptr) {
|
||||||
offset = pDstBox->left;
|
offset = pDstBox->left;
|
||||||
size = pDstBox->right - pDstBox->left;
|
size = pDstBox->right - pDstBox->left;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_context->updateBuffer(
|
if (offset + size > bufferSlice.bufferRange()) {
|
||||||
bufferResource->GetDXVKBuffer(),
|
Logger::err("D3D11: UpdateSubresource: Buffer size out of bounds");
|
||||||
offset, size, pSrcData);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != 0) {
|
||||||
|
m_context->updateBuffer(
|
||||||
|
bufferSlice.buffer(),
|
||||||
|
bufferSlice.bufferOffset() + offset,
|
||||||
|
size, pSrcData);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported");
|
Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported");
|
||||||
}
|
}
|
||||||
@ -628,18 +633,20 @@ namespace dxvk {
|
|||||||
binding.stride = pStrides[i];
|
binding.stride = pStrides[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
DxvkBufferSlice dxvkBinding;
|
DxvkBufferSlice bufferSlice;
|
||||||
|
|
||||||
if (binding.buffer != nullptr) {
|
if (binding.buffer != nullptr) {
|
||||||
Rc<DxvkBuffer> dxvkBuffer = binding.buffer->GetDXVKBuffer();
|
const DxvkBufferSlice baseSlice =
|
||||||
|
binding.buffer->GetCurrentBufferSlice();
|
||||||
|
|
||||||
dxvkBinding = DxvkBufferSlice(
|
bufferSlice = DxvkBufferSlice(
|
||||||
dxvkBuffer, binding.offset,
|
baseSlice.buffer(),
|
||||||
dxvkBuffer->info().size - binding.offset);
|
baseSlice.bufferOffset() + binding.offset,
|
||||||
|
baseSlice.bufferRange() - binding.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_context->bindVertexBuffer(
|
m_context->bindVertexBuffer(
|
||||||
StartSlot + i, dxvkBinding,
|
StartSlot + i, bufferSlice,
|
||||||
binding.stride);
|
binding.stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,17 +662,18 @@ namespace dxvk {
|
|||||||
binding.format = Format;
|
binding.format = Format;
|
||||||
m_state.ia.indexBuffer = binding;
|
m_state.ia.indexBuffer = binding;
|
||||||
|
|
||||||
DxvkBufferSlice dxvkBinding;
|
DxvkBufferSlice bufferSlice;
|
||||||
|
|
||||||
if (binding.buffer != nullptr) {
|
if (binding.buffer != nullptr) {
|
||||||
Rc<DxvkBuffer> dxvkBuffer = binding.buffer->GetDXVKBuffer();
|
const DxvkBufferSlice baseSlice =
|
||||||
|
binding.buffer->GetCurrentBufferSlice();
|
||||||
|
|
||||||
dxvkBinding = DxvkBufferSlice(
|
bufferSlice = DxvkBufferSlice(
|
||||||
dxvkBuffer, binding.offset,
|
baseSlice.buffer(),
|
||||||
dxvkBuffer->info().size - binding.offset);
|
baseSlice.bufferOffset() + binding.offset,
|
||||||
|
baseSlice.bufferRange() - binding.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// As in Vulkan, the index format can be either a 32-bit
|
// As in Vulkan, the index format can be either a 32-bit
|
||||||
// unsigned integer or a 16-bit unsigned integer, no other
|
// unsigned integer or a 16-bit unsigned integer, no other
|
||||||
// formats are allowed.
|
// formats are allowed.
|
||||||
@ -680,7 +688,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_context->bindIndexBuffer(
|
m_context->bindIndexBuffer(
|
||||||
dxvkBinding, indexType);
|
bufferSlice, indexType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1462,13 +1470,10 @@ namespace dxvk {
|
|||||||
pBindings->at(StartSlot + i) = buffer;
|
pBindings->at(StartSlot + i) = buffer;
|
||||||
|
|
||||||
// Figure out which part of the buffer to bind
|
// Figure out which part of the buffer to bind
|
||||||
DxvkBufferSlice bindingInfo;
|
DxvkBufferSlice bufferSlice;
|
||||||
|
|
||||||
if (buffer != nullptr) {
|
if (buffer != nullptr)
|
||||||
bindingInfo = DxvkBufferSlice(
|
bufferSlice = buffer->GetCurrentBufferSlice();
|
||||||
buffer->GetDXVKBuffer(),
|
|
||||||
0, VK_WHOLE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind buffer to the DXVK resource slot
|
// Bind buffer to the DXVK resource slot
|
||||||
const VkPipelineBindPoint bindPoint
|
const VkPipelineBindPoint bindPoint
|
||||||
@ -1481,7 +1486,7 @@ namespace dxvk {
|
|||||||
StartSlot + i);
|
StartSlot + i);
|
||||||
|
|
||||||
m_context->bindResourceBuffer(
|
m_context->bindResourceBuffer(
|
||||||
bindPoint, slotId, bindingInfo);
|
bindPoint, slotId, bufferSlice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1147,14 +1147,17 @@ namespace dxvk {
|
|||||||
void D3D11Device::InitBuffer(
|
void D3D11Device::InitBuffer(
|
||||||
D3D11Buffer* pBuffer,
|
D3D11Buffer* pBuffer,
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
const Rc<DxvkBuffer> buffer = pBuffer->GetDXVKBuffer();
|
const DxvkBufferSlice bufferSlice
|
||||||
|
= pBuffer->GetCurrentBufferSlice();
|
||||||
|
|
||||||
if (pInitialData != nullptr) {
|
if (pInitialData != nullptr) {
|
||||||
std::lock_guard<std::mutex> lock(m_resourceInitMutex);;
|
std::lock_guard<std::mutex> lock(m_resourceInitMutex);;
|
||||||
m_resourceInitContext->beginRecording(
|
m_resourceInitContext->beginRecording(
|
||||||
m_dxvkDevice->createCommandList());
|
m_dxvkDevice->createCommandList());
|
||||||
m_resourceInitContext->updateBuffer(
|
m_resourceInitContext->updateBuffer(
|
||||||
buffer, 0, buffer->info().size,
|
bufferSlice.buffer(),
|
||||||
|
bufferSlice.bufferOffset(),
|
||||||
|
bufferSlice.bufferRange(),
|
||||||
pInitialData->pSysMem);
|
pInitialData->pSysMem);
|
||||||
m_dxvkDevice->submitCommandList(
|
m_dxvkDevice->submitCommandList(
|
||||||
m_resourceInitContext->endRecording(),
|
m_resourceInitContext->endRecording(),
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "../util/util_enum.h"
|
#include "../util/util_enum.h"
|
||||||
#include "../util/util_error.h"
|
#include "../util/util_error.h"
|
||||||
|
#include "../util/util_math.h"
|
||||||
#include "../util/util_string.h"
|
#include "../util/util_string.h"
|
||||||
|
|
||||||
#include <dxgi1_2.h>
|
#include <dxgi1_2.h>
|
||||||
|
@ -57,55 +57,6 @@ namespace dxvk {
|
|||||||
m_layer = pLayer;
|
m_layer = pLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DxgiBufferResource::DxgiBufferResource(
|
|
||||||
IDXGIDevicePrivate* pDevice,
|
|
||||||
const dxvk::DxvkBufferCreateInfo* pCreateInfo,
|
|
||||||
VkMemoryPropertyFlags memoryFlags,
|
|
||||||
UINT usageFlags)
|
|
||||||
: Base(pDevice, usageFlags) {
|
|
||||||
m_buffer = pDevice->GetDXVKDevice()->createBuffer(
|
|
||||||
*pCreateInfo, memoryFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxgiBufferResource::~DxgiBufferResource() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiBufferResource::QueryInterface(REFIID riid, void** ppvObject) {
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, IDXGIObject);
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, IDXGIDeviceSubObject);
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, IDXGIResource);
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, IDXGIBufferResourcePrivate);
|
|
||||||
|
|
||||||
if (m_layer != nullptr)
|
|
||||||
return m_layer->QueryInterface(riid, ppvObject);
|
|
||||||
|
|
||||||
Logger::err("DxgiBufferResource::QueryInterface: Unknown interface query");
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiBufferResource::GetParent(REFIID riid, void** ppParent) {
|
|
||||||
Logger::err("DxgiBufferResource::GetParent: Unknown interface query");
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> STDMETHODCALLTYPE DxgiBufferResource::GetDXVKBuffer() {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE DxgiBufferResource::SetResourceLayer(IUnknown* pLayer) {
|
|
||||||
m_layer = pLayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -127,21 +78,4 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate(
|
|
||||||
IDXGIDevicePrivate* pDevice,
|
|
||||||
const dxvk::DxvkBufferCreateInfo* pCreateInfo,
|
|
||||||
VkMemoryPropertyFlags memoryFlags,
|
|
||||||
UINT usageFlags,
|
|
||||||
IDXGIBufferResourcePrivate** ppResource) {
|
|
||||||
try {
|
|
||||||
*ppResource = dxvk::ref(new dxvk::DxgiBufferResource(
|
|
||||||
pDevice, pCreateInfo, memoryFlags, usageFlags));
|
|
||||||
return S_OK;
|
|
||||||
} catch (const dxvk::DxvkError& e) {
|
|
||||||
dxvk::Logger::err(e.message());
|
|
||||||
return DXGI_ERROR_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -100,45 +100,6 @@ namespace dxvk {
|
|||||||
IUnknown* m_layer = nullptr;
|
IUnknown* m_layer = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Buffer resource
|
|
||||||
*
|
|
||||||
* Stores a DXVK buffer and provides a method to retrieve
|
|
||||||
* it. D3D buffers will be backed by a buffer resource.
|
|
||||||
*/
|
|
||||||
class DxgiBufferResource : public DxgiResource<IDXGIBufferResourcePrivate> {
|
|
||||||
using Base = DxgiResource<IDXGIBufferResourcePrivate>;
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxgiBufferResource(
|
|
||||||
IDXGIDevicePrivate* pDevice,
|
|
||||||
const dxvk::DxvkBufferCreateInfo* pCreateInfo,
|
|
||||||
VkMemoryPropertyFlags memoryFlags,
|
|
||||||
UINT usageFlags);
|
|
||||||
|
|
||||||
~DxgiBufferResource();
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
|
||||||
REFIID riid,
|
|
||||||
void **ppvObject) final;
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetParent(
|
|
||||||
REFIID riid,
|
|
||||||
void **ppParent) final;
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> STDMETHODCALLTYPE GetDXVKBuffer() final;
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE SetResourceLayer(
|
|
||||||
IUnknown* pLayer) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> m_buffer;
|
|
||||||
IUnknown* m_layer = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +113,4 @@ extern "C" {
|
|||||||
UINT usageFlags,
|
UINT usageFlags,
|
||||||
IDXGIImageResourcePrivate** ppResource);
|
IDXGIImageResourcePrivate** ppResource);
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate(
|
|
||||||
IDXGIDevicePrivate* pDevice,
|
|
||||||
const dxvk::DxvkBufferCreateInfo* pCreateInfo,
|
|
||||||
VkMemoryPropertyFlags memoryFlags,
|
|
||||||
UINT usageFlags,
|
|
||||||
IDXGIBufferResourcePrivate** ppResource);
|
|
||||||
|
|
||||||
}
|
}
|
@ -176,7 +176,7 @@ namespace dxvk {
|
|||||||
m_offset(rangeOffset),
|
m_offset(rangeOffset),
|
||||||
m_length(rangeLength) { }
|
m_length(rangeLength) { }
|
||||||
|
|
||||||
Rc<DxvkResource> resource() const {
|
Rc<DxvkBuffer> buffer() const {
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,9 +446,6 @@ namespace dxvk {
|
|||||||
const void* data) {
|
const void* data) {
|
||||||
this->renderPassEnd();
|
this->renderPassEnd();
|
||||||
|
|
||||||
if (size == VK_WHOLE_SIZE)
|
|
||||||
size = buffer->info().size - offset;
|
|
||||||
|
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
// Vulkan specifies that small amounts of data (up to 64kB)
|
// Vulkan specifies that small amounts of data (up to 64kB)
|
||||||
// can be copied to a buffer directly. Anything larger than
|
// can be copied to a buffer directly. Anything larger than
|
||||||
@ -907,7 +904,7 @@ namespace dxvk {
|
|||||||
m_state.vi.indexBuffer.bufferOffset(),
|
m_state.vi.indexBuffer.bufferOffset(),
|
||||||
m_state.vi.indexType);
|
m_state.vi.indexType);
|
||||||
m_cmd->trackResource(
|
m_cmd->trackResource(
|
||||||
m_state.vi.indexBuffer.resource());
|
m_state.vi.indexBuffer.buffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -925,7 +922,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (handle != VK_NULL_HANDLE) {
|
if (handle != VK_NULL_HANDLE) {
|
||||||
m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset);
|
m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset);
|
||||||
m_cmd->trackResource(vbo.resource());
|
m_cmd->trackResource(vbo.buffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,9 @@ namespace dxvk {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T align(T what, T to) {
|
||||||
|
return (what + to - 1) & ~(to - 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user