mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 19:24:10 +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(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_BUFFER_DESC* pDesc)
|
||||
: m_device (pDevice),
|
||||
m_desc (*pDesc) {
|
||||
: m_device (pDevice),
|
||||
m_desc (*pDesc),
|
||||
m_buffer (CreateBuffer(pDesc)) {
|
||||
|
||||
}
|
||||
|
||||
@ -62,7 +63,7 @@ namespace dxvk {
|
||||
D3D11_MAP MapType,
|
||||
UINT MapFlags,
|
||||
D3D11_MAPPED_SUBRESOURCE* pMappedSubresource) {
|
||||
const Rc<DxvkBuffer> buffer = GetDXVKBuffer();
|
||||
const Rc<DxvkBuffer> buffer = m_buffer;
|
||||
|
||||
if (buffer->mapPtr(0) == nullptr) {
|
||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||
@ -122,8 +123,13 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkBuffer> D3D11Buffer::GetDXVKBuffer() {
|
||||
return m_buffer;
|
||||
DxvkBufferSlice D3D11Buffer::GetCurrentBufferSlice() const {
|
||||
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 D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
|
||||
class D3D11BufferStorage {
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
|
||||
static constexpr VkDeviceSize BufferSliceAlignment = 64;
|
||||
public:
|
||||
|
||||
D3D11Buffer(
|
||||
@ -46,14 +55,15 @@ namespace dxvk {
|
||||
void Unmap(
|
||||
D3D11DeviceContext* pContext);
|
||||
|
||||
Rc<DxvkBuffer> GetDXVKBuffer();
|
||||
DxvkBufferSlice GetCurrentBufferSlice() const;
|
||||
DxvkBufferSlice GetInitialBufferSlice() const;
|
||||
|
||||
private:
|
||||
|
||||
Com<D3D11Device> m_device;
|
||||
D3D11_BUFFER_DESC m_desc;
|
||||
const Com<D3D11Device> m_device;
|
||||
const D3D11_BUFFER_DESC m_desc;
|
||||
|
||||
Rc<DxvkBuffer> m_buffer;
|
||||
Rc<DxvkBuffer> m_buffer;
|
||||
|
||||
Rc<DxvkBuffer> CreateBuffer(
|
||||
const D3D11_BUFFER_DESC* pDesc) const;
|
||||
|
@ -395,23 +395,28 @@ namespace dxvk {
|
||||
pDstResource->GetType(&resourceType);
|
||||
|
||||
if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||
Com<IDXGIBufferResourcePrivate> bufferResource;
|
||||
|
||||
pDstResource->QueryInterface(
|
||||
__uuidof(IDXGIBufferResourcePrivate),
|
||||
reinterpret_cast<void**>(&bufferResource));
|
||||
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
|
||||
const auto bufferSlice = bufferResource->GetCurrentBufferSlice();
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
VkDeviceSize size = VK_WHOLE_SIZE;
|
||||
VkDeviceSize size = bufferSlice.bufferRange();
|
||||
|
||||
if (pDstBox != nullptr) {
|
||||
offset = pDstBox->left;
|
||||
size = pDstBox->right - pDstBox->left;
|
||||
}
|
||||
|
||||
m_context->updateBuffer(
|
||||
bufferResource->GetDXVKBuffer(),
|
||||
offset, size, pSrcData);
|
||||
if (offset + size > bufferSlice.bufferRange()) {
|
||||
Logger::err("D3D11: UpdateSubresource: Buffer size out of bounds");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size != 0) {
|
||||
m_context->updateBuffer(
|
||||
bufferSlice.buffer(),
|
||||
bufferSlice.bufferOffset() + offset,
|
||||
size, pSrcData);
|
||||
}
|
||||
} else {
|
||||
Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported");
|
||||
}
|
||||
@ -628,18 +633,20 @@ namespace dxvk {
|
||||
binding.stride = pStrides[i];
|
||||
}
|
||||
|
||||
DxvkBufferSlice dxvkBinding;
|
||||
DxvkBufferSlice bufferSlice;
|
||||
|
||||
if (binding.buffer != nullptr) {
|
||||
Rc<DxvkBuffer> dxvkBuffer = binding.buffer->GetDXVKBuffer();
|
||||
const DxvkBufferSlice baseSlice =
|
||||
binding.buffer->GetCurrentBufferSlice();
|
||||
|
||||
dxvkBinding = DxvkBufferSlice(
|
||||
dxvkBuffer, binding.offset,
|
||||
dxvkBuffer->info().size - binding.offset);
|
||||
bufferSlice = DxvkBufferSlice(
|
||||
baseSlice.buffer(),
|
||||
baseSlice.bufferOffset() + binding.offset,
|
||||
baseSlice.bufferRange() - binding.offset);
|
||||
}
|
||||
|
||||
m_context->bindVertexBuffer(
|
||||
StartSlot + i, dxvkBinding,
|
||||
StartSlot + i, bufferSlice,
|
||||
binding.stride);
|
||||
}
|
||||
}
|
||||
@ -655,17 +662,18 @@ namespace dxvk {
|
||||
binding.format = Format;
|
||||
m_state.ia.indexBuffer = binding;
|
||||
|
||||
DxvkBufferSlice dxvkBinding;
|
||||
DxvkBufferSlice bufferSlice;
|
||||
|
||||
if (binding.buffer != nullptr) {
|
||||
Rc<DxvkBuffer> dxvkBuffer = binding.buffer->GetDXVKBuffer();
|
||||
const DxvkBufferSlice baseSlice =
|
||||
binding.buffer->GetCurrentBufferSlice();
|
||||
|
||||
dxvkBinding = DxvkBufferSlice(
|
||||
dxvkBuffer, binding.offset,
|
||||
dxvkBuffer->info().size - binding.offset);
|
||||
bufferSlice = DxvkBufferSlice(
|
||||
baseSlice.buffer(),
|
||||
baseSlice.bufferOffset() + binding.offset,
|
||||
baseSlice.bufferRange() - binding.offset);
|
||||
}
|
||||
|
||||
|
||||
// As in Vulkan, the index format can be either a 32-bit
|
||||
// unsigned integer or a 16-bit unsigned integer, no other
|
||||
// formats are allowed.
|
||||
@ -680,7 +688,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
m_context->bindIndexBuffer(
|
||||
dxvkBinding, indexType);
|
||||
bufferSlice, indexType);
|
||||
}
|
||||
|
||||
|
||||
@ -1462,13 +1470,10 @@ namespace dxvk {
|
||||
pBindings->at(StartSlot + i) = buffer;
|
||||
|
||||
// Figure out which part of the buffer to bind
|
||||
DxvkBufferSlice bindingInfo;
|
||||
DxvkBufferSlice bufferSlice;
|
||||
|
||||
if (buffer != nullptr) {
|
||||
bindingInfo = DxvkBufferSlice(
|
||||
buffer->GetDXVKBuffer(),
|
||||
0, VK_WHOLE_SIZE);
|
||||
}
|
||||
if (buffer != nullptr)
|
||||
bufferSlice = buffer->GetCurrentBufferSlice();
|
||||
|
||||
// Bind buffer to the DXVK resource slot
|
||||
const VkPipelineBindPoint bindPoint
|
||||
@ -1481,7 +1486,7 @@ namespace dxvk {
|
||||
StartSlot + i);
|
||||
|
||||
m_context->bindResourceBuffer(
|
||||
bindPoint, slotId, bindingInfo);
|
||||
bindPoint, slotId, bufferSlice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1147,14 +1147,17 @@ namespace dxvk {
|
||||
void D3D11Device::InitBuffer(
|
||||
D3D11Buffer* pBuffer,
|
||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||
const Rc<DxvkBuffer> buffer = pBuffer->GetDXVKBuffer();
|
||||
const DxvkBufferSlice bufferSlice
|
||||
= pBuffer->GetCurrentBufferSlice();
|
||||
|
||||
if (pInitialData != nullptr) {
|
||||
std::lock_guard<std::mutex> lock(m_resourceInitMutex);;
|
||||
m_resourceInitContext->beginRecording(
|
||||
m_dxvkDevice->createCommandList());
|
||||
m_resourceInitContext->updateBuffer(
|
||||
buffer, 0, buffer->info().size,
|
||||
bufferSlice.buffer(),
|
||||
bufferSlice.bufferOffset(),
|
||||
bufferSlice.bufferRange(),
|
||||
pInitialData->pSysMem);
|
||||
m_dxvkDevice->submitCommandList(
|
||||
m_resourceInitContext->endRecording(),
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "../util/util_enum.h"
|
||||
#include "../util/util_error.h"
|
||||
#include "../util/util_math.h"
|
||||
#include "../util/util_string.h"
|
||||
|
||||
#include <dxgi1_2.h>
|
||||
|
@ -57,55 +57,6 @@ namespace dxvk {
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \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,
|
||||
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_length(rangeLength) { }
|
||||
|
||||
Rc<DxvkResource> resource() const {
|
||||
Rc<DxvkBuffer> buffer() const {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
|
@ -446,9 +446,6 @@ namespace dxvk {
|
||||
const void* data) {
|
||||
this->renderPassEnd();
|
||||
|
||||
if (size == VK_WHOLE_SIZE)
|
||||
size = buffer->info().size - offset;
|
||||
|
||||
if (size != 0) {
|
||||
// Vulkan specifies that small amounts of data (up to 64kB)
|
||||
// can be copied to a buffer directly. Anything larger than
|
||||
@ -907,7 +904,7 @@ namespace dxvk {
|
||||
m_state.vi.indexBuffer.bufferOffset(),
|
||||
m_state.vi.indexType);
|
||||
m_cmd->trackResource(
|
||||
m_state.vi.indexBuffer.resource());
|
||||
m_state.vi.indexBuffer.buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -925,7 +922,7 @@ namespace dxvk {
|
||||
|
||||
if (handle != VK_NULL_HANDLE) {
|
||||
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;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T align(T what, T to) {
|
||||
return (what + to - 1) & ~(to - 1);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user