mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-29 04:06:24 +01:00
[dxvk] Rework buffer view creation
This commit is contained in:
parent
1fd3c8040d
commit
088ba404a6
@ -339,7 +339,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset),
|
cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset),
|
||||||
cSrcSlice = counterView->slice()
|
cSrcSlice = DxvkBufferSlice(counterView)
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->copyBuffer(
|
ctx->copyBuffer(
|
||||||
cDstSlice.buffer(),
|
cDstSlice.buffer(),
|
||||||
@ -446,7 +446,7 @@ namespace dxvk {
|
|||||||
|| bufferView->info().format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
|
|| bufferView->info().format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cClearValue = clearValue.color.uint32[0],
|
cClearValue = clearValue.color.uint32[0],
|
||||||
cDstSlice = bufferView->slice()
|
cDstSlice = DxvkBufferSlice(bufferView)
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->clearBuffer(
|
ctx->clearBuffer(
|
||||||
cDstSlice.buffer(),
|
cDstSlice.buffer(),
|
||||||
@ -460,8 +460,7 @@ namespace dxvk {
|
|||||||
DxvkBufferViewCreateInfo info = bufferView->info();
|
DxvkBufferViewCreateInfo info = bufferView->info();
|
||||||
info.format = rawFormat;
|
info.format = rawFormat;
|
||||||
|
|
||||||
bufferView = m_device->createBufferView(
|
bufferView = bufferView->buffer()->createView(info);
|
||||||
bufferView->buffer(), info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
@ -534,8 +533,7 @@ namespace dxvk {
|
|||||||
bufferViewInfo.rangeLength = bufferInfo.size;
|
bufferViewInfo.rangeLength = bufferInfo.size;
|
||||||
bufferViewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
bufferViewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||||
|
|
||||||
Rc<DxvkBufferView> bufferView = m_device->createBufferView(buffer,
|
Rc<DxvkBufferView> bufferView = buffer->createView(bufferViewInfo);
|
||||||
bufferViewInfo);
|
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstView = std::move(imageView),
|
cDstView = std::move(imageView),
|
||||||
@ -3781,7 +3779,7 @@ namespace dxvk {
|
|||||||
: VK_SHADER_STAGE_ALL_GRAPHICS;
|
: VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||||
|
|
||||||
if (cCounterView != nullptr && cCounterValue != ~0u) {
|
if (cCounterView != nullptr && cCounterValue != ~0u) {
|
||||||
auto counterSlice = cCounterView->slice();
|
DxvkBufferSlice counterSlice(cCounterView);
|
||||||
|
|
||||||
ctx->updateBuffer(
|
ctx->updateBuffer(
|
||||||
counterSlice.buffer(),
|
counterSlice.buffer(),
|
||||||
|
@ -61,7 +61,7 @@ namespace dxvk {
|
|||||||
if (counterView == nullptr)
|
if (counterView == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto counterSlice = counterView->slice();
|
DxvkBufferSlice counterSlice(counterView);
|
||||||
|
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||||
m_transferCommands += 1;
|
m_transferCommands += 1;
|
||||||
|
@ -69,8 +69,7 @@ namespace dxvk {
|
|||||||
m_info.Buffer.Length = viewInfo.rangeLength;
|
m_info.Buffer.Length = viewInfo.rangeLength;
|
||||||
|
|
||||||
// Create underlying buffer view object
|
// Create underlying buffer view object
|
||||||
m_bufferView = pDevice->GetDXVKDevice()->createBufferView(
|
m_bufferView = buffer->GetBuffer()->createView(viewInfo);
|
||||||
buffer->GetBuffer(), viewInfo);
|
|
||||||
} else {
|
} else {
|
||||||
auto texture = GetCommonTexture(pResource);
|
auto texture = GetCommonTexture(pResource);
|
||||||
auto formatInfo = pDevice->LookupFormat(pDesc->Format, texture->GetFormatMode());
|
auto formatInfo = pDevice->LookupFormat(pDesc->Format, texture->GetFormatMode());
|
||||||
|
@ -51,8 +51,7 @@ namespace dxvk {
|
|||||||
m_info.Buffer.Offset = viewInfo.rangeOffset;
|
m_info.Buffer.Offset = viewInfo.rangeOffset;
|
||||||
m_info.Buffer.Length = viewInfo.rangeLength;
|
m_info.Buffer.Length = viewInfo.rangeLength;
|
||||||
|
|
||||||
m_bufferView = pDevice->GetDXVKDevice()->createBufferView(
|
m_bufferView = buffer->GetBuffer()->createView(viewInfo);
|
||||||
buffer->GetBuffer(), viewInfo);
|
|
||||||
} else {
|
} else {
|
||||||
auto texture = GetCommonTexture(pResource);
|
auto texture = GetCommonTexture(pResource);
|
||||||
auto formatInfo = pDevice->LookupFormat(pDesc->Format, texture->GetFormatMode());
|
auto formatInfo = pDevice->LookupFormat(pDesc->Format, texture->GetFormatMode());
|
||||||
@ -457,7 +456,7 @@ namespace dxvk {
|
|||||||
viewInfo.rangeLength = sizeof(uint32_t);
|
viewInfo.rangeLength = sizeof(uint32_t);
|
||||||
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||||
|
|
||||||
return device->createBufferView(buffer, viewInfo);
|
return buffer->createView(viewInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace dxvk {
|
|||||||
bufferViewInfo.rangeOffset = srcSlice.offset();
|
bufferViewInfo.rangeOffset = srcSlice.offset();
|
||||||
bufferViewInfo.rangeLength = srcSlice.length();
|
bufferViewInfo.rangeLength = srcSlice.length();
|
||||||
bufferViewInfo.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
bufferViewInfo.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
||||||
auto tmpBufferView = m_device->createBufferView(srcSlice.buffer(), bufferViewInfo);
|
auto tmpBufferView = srcSlice.buffer()->createView(bufferViewInfo);
|
||||||
|
|
||||||
m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue);
|
m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue);
|
||||||
m_context->bindResourceImageView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView));
|
m_context->bindResourceImageView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView));
|
||||||
|
@ -41,80 +41,20 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkBufferView> DxvkBuffer::createView(
|
||||||
DxvkBufferView::DxvkBufferView(
|
const DxvkBufferViewCreateInfo& info) {
|
||||||
DxvkDevice* device,
|
DxvkBufferViewKey key = { };
|
||||||
const Rc<DxvkBuffer>& buffer,
|
key.format = info.format;
|
||||||
const DxvkBufferViewCreateInfo& info)
|
key.offset = info.rangeOffset;
|
||||||
: m_vkd(device->vkd()), m_info(info), m_buffer(buffer),
|
key.size = info.rangeLength;
|
||||||
m_usage (device->features().khrMaintenance5.maintenance5 ? info.usage : 0u),
|
key.usage = info.usage;
|
||||||
m_bufferSlice (getSliceHandle()),
|
|
||||||
m_bufferView (VK_NULL_HANDLE) {
|
|
||||||
if (m_info.format != VK_FORMAT_UNDEFINED)
|
|
||||||
m_bufferView = createBufferView(m_bufferSlice);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkBufferView::~DxvkBufferView() {
|
|
||||||
if (m_views.empty()) {
|
|
||||||
m_vkd->vkDestroyBufferView(
|
|
||||||
m_vkd->device(), m_bufferView, nullptr);
|
|
||||||
} else {
|
|
||||||
for (const auto& pair : m_views) {
|
|
||||||
m_vkd->vkDestroyBufferView(
|
|
||||||
m_vkd->device(), pair.second, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkBufferView DxvkBufferView::createBufferView(
|
|
||||||
const DxvkBufferSliceHandle& slice) {
|
|
||||||
VkBufferUsageFlags2CreateInfoKHR viewFlags = { VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR };
|
|
||||||
viewFlags.usage = m_usage;
|
|
||||||
|
|
||||||
VkBufferViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO };
|
std::unique_lock lock(m_viewMutex);
|
||||||
viewInfo.buffer = slice.handle;
|
|
||||||
viewInfo.format = m_info.format;
|
|
||||||
viewInfo.offset = slice.offset;
|
|
||||||
viewInfo.range = slice.length;
|
|
||||||
|
|
||||||
if (m_usage)
|
auto entry = m_views.emplace(std::piecewise_construct,
|
||||||
viewInfo.pNext = &viewFlags;
|
std::make_tuple(key), std::make_tuple(this, key));
|
||||||
|
|
||||||
VkBufferView result = VK_NULL_HANDLE;
|
return &entry.first->second;
|
||||||
|
|
||||||
if (m_vkd->vkCreateBufferView(m_vkd->device(),
|
|
||||||
&viewInfo, nullptr, &result) != VK_SUCCESS) {
|
|
||||||
throw DxvkError(str::format(
|
|
||||||
"DxvkBufferView: Failed to create buffer view:",
|
|
||||||
"\n Offset: ", viewInfo.offset,
|
|
||||||
"\n Range: ", viewInfo.range,
|
|
||||||
"\n Format: ", viewInfo.format));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
void DxvkBufferView::updateBufferView(
|
|
||||||
const DxvkBufferSliceHandle& slice) {
|
|
||||||
if (m_info.format != VK_FORMAT_UNDEFINED) {
|
|
||||||
if (m_views.empty())
|
|
||||||
m_views.insert({ m_bufferSlice, m_bufferView });
|
|
||||||
|
|
||||||
m_bufferSlice = slice;
|
|
||||||
|
|
||||||
auto entry = m_views.find(slice);
|
|
||||||
if (entry != m_views.end()) {
|
|
||||||
m_bufferView = entry->second;
|
|
||||||
} else {
|
|
||||||
m_bufferView = createBufferView(m_bufferSlice);
|
|
||||||
m_views.insert({ m_bufferSlice, m_bufferView });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_bufferSlice = slice;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Buffer create info
|
* \brief Buffer create info
|
||||||
*
|
*
|
||||||
@ -103,6 +105,87 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Virtual buffer view
|
||||||
|
*/
|
||||||
|
class DxvkBufferView : public DxvkResource {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkBufferView(
|
||||||
|
DxvkBuffer* buffer,
|
||||||
|
const DxvkBufferViewKey& key)
|
||||||
|
: m_buffer(buffer), m_key(key) { }
|
||||||
|
|
||||||
|
void incRef();
|
||||||
|
void decRef();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves buffer view handle
|
||||||
|
*
|
||||||
|
* Creates a new view if the buffer has been invalidated.
|
||||||
|
* \returns Vulkan buffer view handle
|
||||||
|
*/
|
||||||
|
VkBufferView handle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves buffer slice handle
|
||||||
|
* \returns Buffer slice handle
|
||||||
|
*/
|
||||||
|
DxvkBufferSliceHandle getSliceHandle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Element count
|
||||||
|
*
|
||||||
|
* Number of typed elements contained in the buffer view.
|
||||||
|
* Depends on the buffer view format.
|
||||||
|
* \returns Element count
|
||||||
|
*/
|
||||||
|
VkDeviceSize elementCount() const {
|
||||||
|
auto format = lookupFormatInfo(m_key.format);
|
||||||
|
return m_key.size / format->elementSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Buffer view properties
|
||||||
|
* \returns Buffer view properties
|
||||||
|
*/
|
||||||
|
DxvkBufferViewCreateInfo info() const {
|
||||||
|
DxvkBufferViewCreateInfo info = { };
|
||||||
|
info.format = m_key.format;
|
||||||
|
info.rangeOffset = m_key.offset;
|
||||||
|
info.rangeLength = m_key.size;
|
||||||
|
info.usage = m_key.usage;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Underlying buffer object
|
||||||
|
* \returns Underlying buffer object
|
||||||
|
*/
|
||||||
|
DxvkBuffer* buffer() const {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief View format info
|
||||||
|
* \returns View format info
|
||||||
|
*/
|
||||||
|
const DxvkFormatInfo* formatInfo() const {
|
||||||
|
return lookupFormatInfo(m_key.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DxvkBuffer* m_buffer = nullptr;
|
||||||
|
DxvkBufferViewKey m_key = { };
|
||||||
|
|
||||||
|
uint32_t m_version = 0u;
|
||||||
|
VkBufferView m_handle = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Virtual buffer resource
|
* \brief Virtual buffer resource
|
||||||
*
|
*
|
||||||
@ -111,7 +194,7 @@ namespace dxvk {
|
|||||||
* if allocated on an appropriate memory type.
|
* if allocated on an appropriate memory type.
|
||||||
*/
|
*/
|
||||||
class DxvkBuffer : public DxvkPagedResource {
|
class DxvkBuffer : public DxvkPagedResource {
|
||||||
friend class DxvkBufferView;
|
friend DxvkBufferView;
|
||||||
|
|
||||||
constexpr static VkDeviceSize MaxAllocationSize = DxvkPageAllocator::PageSize;
|
constexpr static VkDeviceSize MaxAllocationSize = DxvkPageAllocator::PageSize;
|
||||||
constexpr static VkDeviceSize MinAllocationSize = DxvkPoolAllocator::MinSize;
|
constexpr static VkDeviceSize MinAllocationSize = DxvkPoolAllocator::MinSize;
|
||||||
@ -273,6 +356,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_storage = std::move(slice);
|
m_storage = std::move(slice);
|
||||||
m_bufferInfo = m_storage->getBufferInfo();
|
m_bufferInfo = m_storage->getBufferInfo();
|
||||||
|
|
||||||
|
// Implicitly invalidate views
|
||||||
|
m_version += 1u;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +378,15 @@ namespace dxvk {
|
|||||||
return m_import.buffer != VK_NULL_HANDLE;
|
return m_import.buffer != VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates or retrieves a buffer view
|
||||||
|
*
|
||||||
|
* \param [in] info Buffer view create info
|
||||||
|
* \returns Newly created buffer view
|
||||||
|
*/
|
||||||
|
Rc<DxvkBufferView> createView(
|
||||||
|
const DxvkBufferViewCreateInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
Rc<vk::DeviceFn> m_vkd;
|
||||||
@ -302,12 +397,17 @@ namespace dxvk {
|
|||||||
DxvkBufferCreateInfo m_info = { };
|
DxvkBufferCreateInfo m_info = { };
|
||||||
DxvkBufferImportInfo m_import = { };
|
DxvkBufferImportInfo m_import = { };
|
||||||
|
|
||||||
VkDeviceSize m_xfbStride = 0u;
|
uint32_t m_xfbStride = 0u;
|
||||||
|
uint32_t m_version = 0u;
|
||||||
|
|
||||||
DxvkResourceBufferInfo m_bufferInfo = { };
|
DxvkResourceBufferInfo m_bufferInfo = { };
|
||||||
|
|
||||||
Rc<DxvkResourceAllocation> m_storage;
|
Rc<DxvkResourceAllocation> m_storage;
|
||||||
|
|
||||||
|
dxvk::mutex m_viewMutex;
|
||||||
|
std::unordered_map<DxvkBufferViewKey,
|
||||||
|
DxvkBufferView, DxvkHash, DxvkEq> m_views;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -323,17 +423,20 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkBufferSlice() { }
|
DxvkBufferSlice() { }
|
||||||
|
|
||||||
DxvkBufferSlice(
|
DxvkBufferSlice(
|
||||||
const Rc<DxvkBuffer>& buffer,
|
Rc<DxvkBuffer> buffer,
|
||||||
VkDeviceSize rangeOffset,
|
VkDeviceSize rangeOffset,
|
||||||
VkDeviceSize rangeLength)
|
VkDeviceSize rangeLength)
|
||||||
: m_buffer(buffer),
|
: m_buffer(std::move(buffer)),
|
||||||
m_offset(rangeOffset),
|
m_offset(rangeOffset),
|
||||||
m_length(rangeLength) { }
|
m_length(rangeLength) { }
|
||||||
|
|
||||||
explicit DxvkBufferSlice(const Rc<DxvkBuffer>& buffer)
|
explicit DxvkBufferSlice(Rc<DxvkBuffer> buffer)
|
||||||
: DxvkBufferSlice(buffer, 0, buffer->info().size) { }
|
: DxvkBufferSlice(std::move(buffer), 0, buffer->info().size) { }
|
||||||
|
|
||||||
|
explicit DxvkBufferSlice(const Rc<DxvkBufferView>& view)
|
||||||
|
: DxvkBufferSlice(view->buffer(), view->info().rangeOffset, view->info().rangeLength) { }
|
||||||
|
|
||||||
DxvkBufferSlice(const DxvkBufferSlice& ) = default;
|
DxvkBufferSlice(const DxvkBufferSlice& ) = default;
|
||||||
DxvkBufferSlice( DxvkBufferSlice&&) = default;
|
DxvkBufferSlice( DxvkBufferSlice&&) = default;
|
||||||
@ -502,135 +605,31 @@ namespace dxvk {
|
|||||||
VkDeviceSize m_length = 0;
|
VkDeviceSize m_length = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Buffer view
|
|
||||||
*
|
|
||||||
* Allows the application to interpret buffer
|
|
||||||
* contents like formatted pixel data. These
|
|
||||||
* buffer views are used as texel buffers.
|
|
||||||
*/
|
|
||||||
class DxvkBufferView : public DxvkResource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkBufferView(
|
|
||||||
DxvkDevice* device,
|
|
||||||
const Rc<DxvkBuffer>& buffer,
|
|
||||||
const DxvkBufferViewCreateInfo& info);
|
|
||||||
|
|
||||||
~DxvkBufferView();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Buffer view handle
|
|
||||||
* \returns Buffer view handle
|
|
||||||
*/
|
|
||||||
VkBufferView handle() const {
|
|
||||||
return m_bufferView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Element cound
|
|
||||||
*
|
|
||||||
* Number of typed elements contained
|
|
||||||
* in the buffer view. Depends on the
|
|
||||||
* buffer view format.
|
|
||||||
* \returns Element count
|
|
||||||
*/
|
|
||||||
VkDeviceSize elementCount() const {
|
|
||||||
auto format = lookupFormatInfo(m_info.format);
|
|
||||||
return m_info.rangeLength / format->elementSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Buffer view properties
|
|
||||||
* \returns Buffer view properties
|
|
||||||
*/
|
|
||||||
const DxvkBufferViewCreateInfo& info() const {
|
|
||||||
return m_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Underlying buffer object
|
|
||||||
* \returns Underlying buffer object
|
|
||||||
*/
|
|
||||||
const Rc<DxvkBuffer>& buffer() const {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Underlying buffer info
|
|
||||||
* \returns Underlying buffer info
|
|
||||||
*/
|
|
||||||
const DxvkBufferCreateInfo& bufferInfo() const {
|
|
||||||
return m_buffer->info();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief View format info
|
|
||||||
* \returns View format info
|
|
||||||
*/
|
|
||||||
const DxvkFormatInfo* formatInfo() const {
|
|
||||||
return lookupFormatInfo(m_info.format);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves buffer slice handle
|
|
||||||
* \returns Buffer slice handle
|
|
||||||
*/
|
|
||||||
DxvkBufferSliceHandle getSliceHandle() const {
|
|
||||||
return m_buffer->getSliceHandle(
|
|
||||||
m_info.rangeOffset,
|
|
||||||
m_info.rangeLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Underlying buffer slice
|
|
||||||
* \returns Slice backing the view
|
|
||||||
*/
|
|
||||||
DxvkBufferSlice slice() const {
|
|
||||||
return DxvkBufferSlice(m_buffer,
|
|
||||||
m_info.rangeOffset,
|
|
||||||
m_info.rangeLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Updates the buffer view
|
|
||||||
*
|
|
||||||
* If the buffer has been invalidated ever since
|
|
||||||
* the view was created, the view is invalid as
|
|
||||||
* well and needs to be re-created. Call this
|
|
||||||
* prior to using the buffer view handle.
|
|
||||||
*/
|
|
||||||
void updateView() {
|
|
||||||
DxvkBufferSliceHandle slice = getSliceHandle();
|
|
||||||
|
|
||||||
if (!m_bufferSlice.eq(slice))
|
|
||||||
this->updateBufferView(slice);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
DxvkBufferViewCreateInfo m_info;
|
|
||||||
Rc<DxvkBuffer> m_buffer;
|
|
||||||
VkBufferUsageFlags m_usage;
|
|
||||||
|
|
||||||
DxvkBufferSliceHandle m_bufferSlice;
|
inline VkBufferView DxvkBufferView::handle() {
|
||||||
VkBufferView m_bufferView;
|
if (likely(m_version == m_buffer->m_version))
|
||||||
|
return m_handle;
|
||||||
|
|
||||||
std::unordered_map<
|
m_handle = m_buffer->m_storage->createBufferView(m_key);
|
||||||
DxvkBufferSliceHandle,
|
m_version = m_buffer->m_version;
|
||||||
VkBufferView,
|
return m_handle;
|
||||||
DxvkHash, DxvkEq> m_views;
|
}
|
||||||
|
|
||||||
VkBufferView createBufferView(
|
|
||||||
const DxvkBufferSliceHandle& slice);
|
inline DxvkBufferSliceHandle DxvkBufferView::getSliceHandle() const {
|
||||||
|
return m_buffer->getSliceHandle(m_key.offset, m_key.size);
|
||||||
void updateBufferView(
|
}
|
||||||
const DxvkBufferSliceHandle& slice);
|
|
||||||
|
|
||||||
};
|
inline void DxvkBufferView::incRef() {
|
||||||
|
m_buffer->incRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void DxvkBufferView::decRef() {
|
||||||
|
m_buffer->decRef();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -261,6 +261,12 @@ namespace dxvk {
|
|||||||
m_resources.trackResource<Access>(rc.ptr());
|
m_resources.trackResource<Access>(rc.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<DxvkAccess Access, typename T>
|
||||||
|
void trackResource(T* rc) {
|
||||||
|
// TODO remove this jank once things are refactored
|
||||||
|
m_resources.trackResource<Access>(rc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Tracks a GPU event
|
* \brief Tracks a GPU event
|
||||||
*
|
*
|
||||||
|
@ -253,10 +253,6 @@ namespace dxvk {
|
|||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
this->invalidateState();
|
this->invalidateState();
|
||||||
|
|
||||||
// The view range might have been invalidated, so
|
|
||||||
// we need to make sure the handle is up to date
|
|
||||||
bufferView->updateView();
|
|
||||||
|
|
||||||
auto bufferSlice = bufferView->getSliceHandle();
|
auto bufferSlice = bufferView->getSliceHandle();
|
||||||
|
|
||||||
if (m_execBarriers.isBufferDirty(bufferSlice, DxvkAccess::Write))
|
if (m_execBarriers.isBufferDirty(bufferSlice, DxvkAccess::Write))
|
||||||
@ -308,8 +304,8 @@ namespace dxvk {
|
|||||||
m_execBarriers.accessBuffer(bufferSlice,
|
m_execBarriers.accessBuffer(bufferSlice,
|
||||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
VK_ACCESS_SHADER_WRITE_BIT,
|
VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
bufferView->bufferInfo().stages,
|
bufferView->buffer()->info().stages,
|
||||||
bufferView->bufferInfo().access);
|
bufferView->buffer()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(bufferView);
|
m_cmd->trackResource<DxvkAccess::None>(bufferView);
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(bufferView->buffer());
|
m_cmd->trackResource<DxvkAccess::Write>(bufferView->buffer());
|
||||||
@ -874,7 +870,7 @@ namespace dxvk {
|
|||||||
viewInfo.rangeOffset = dstBufferOffset;
|
viewInfo.rangeOffset = dstBufferOffset;
|
||||||
viewInfo.rangeLength = dstBufferSlice.length;
|
viewInfo.rangeLength = dstBufferSlice.length;
|
||||||
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||||
Rc<DxvkBufferView> dstView = m_device->createBufferView(dstBuffer, viewInfo);
|
Rc<DxvkBufferView> dstView = dstBuffer->createView(viewInfo);
|
||||||
|
|
||||||
viewInfo.rangeOffset = srcBufferOffset;
|
viewInfo.rangeOffset = srcBufferOffset;
|
||||||
viewInfo.rangeLength = srcBufferSlice.length;
|
viewInfo.rangeLength = srcBufferSlice.length;
|
||||||
@ -917,11 +913,11 @@ namespace dxvk {
|
|||||||
VK_ACCESS_SHADER_READ_BIT);
|
VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
|
||||||
viewInfo.rangeOffset = 0;
|
viewInfo.rangeOffset = 0;
|
||||||
srcView = m_device->createBufferView(tmpBuffer, viewInfo);
|
srcView = tmpBuffer->createView(viewInfo);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(tmpBuffer);
|
m_cmd->trackResource<DxvkAccess::Write>(tmpBuffer);
|
||||||
} else {
|
} else {
|
||||||
srcView = m_device->createBufferView(srcBuffer, viewInfo);
|
srcView = srcBuffer->createView(viewInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pipeInfo = m_common->metaCopy().getCopyBufferImagePipeline();
|
auto pipeInfo = m_common->metaCopy().getCopyBufferImagePipeline();
|
||||||
@ -1076,8 +1072,8 @@ namespace dxvk {
|
|||||||
tmpViewInfoS.rangeLength = dataSizeS;
|
tmpViewInfoS.rangeLength = dataSizeS;
|
||||||
tmpViewInfoS.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
tmpViewInfoS.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
||||||
|
|
||||||
auto tmpBufferViewD = m_device->createBufferView(tmpBuffer, tmpViewInfoD);
|
auto tmpBufferViewD = tmpBuffer->createView(tmpViewInfoD);
|
||||||
auto tmpBufferViewS = m_device->createBufferView(tmpBuffer, tmpViewInfoS);
|
auto tmpBufferViewS = tmpBuffer->createView(tmpViewInfoS);
|
||||||
|
|
||||||
// Create descriptor set for the unpack operation
|
// Create descriptor set for the unpack operation
|
||||||
DxvkMetaUnpackDescriptors descriptors;
|
DxvkMetaUnpackDescriptors descriptors;
|
||||||
@ -5326,7 +5322,6 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.bufferView != nullptr) {
|
if (res.bufferView != nullptr) {
|
||||||
res.bufferView->updateView();
|
|
||||||
descriptorInfo.texelBuffer = res.bufferView->handle();
|
descriptorInfo.texelBuffer = res.bufferView->handle();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
@ -5342,7 +5337,6 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.bufferView != nullptr) {
|
if (res.bufferView != nullptr) {
|
||||||
res.bufferView->updateView();
|
|
||||||
descriptorInfo.texelBuffer = res.bufferView->handle();
|
descriptorInfo.texelBuffer = res.bufferView->handle();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
@ -6106,7 +6100,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) {
|
for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) {
|
||||||
if ((slices[i]->length())
|
if ((slices[i]->length())
|
||||||
&& (slices[i]->bufferInfo().access & storageBufferAccess)) {
|
&& (slices[i]->buffer()->info().access & storageBufferAccess)) {
|
||||||
requiresBarrier = this->checkBufferBarrier<DoEmit>(*slices[i],
|
requiresBarrier = this->checkBufferBarrier<DoEmit>(*slices[i],
|
||||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
|
VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
|
||||||
@ -6191,8 +6185,7 @@ namespace dxvk {
|
|||||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||||
if ((slot.bufferView != nullptr)
|
if ((slot.bufferView != nullptr)
|
||||||
&& (slot.bufferView->bufferInfo().access & storageBufferAccess)) {
|
&& (slot.bufferView->buffer()->info().access & storageBufferAccess)) {
|
||||||
slot.bufferView->updateView();
|
|
||||||
requiresBarrier = this->checkBufferViewBarrier<DoEmit>(slot.bufferView,
|
requiresBarrier = this->checkBufferViewBarrier<DoEmit>(slot.bufferView,
|
||||||
util::pipelineStages(binding.stage), binding.access);
|
util::pipelineStages(binding.stage), binding.access);
|
||||||
}
|
}
|
||||||
@ -6258,8 +6251,8 @@ namespace dxvk {
|
|||||||
m_execBarriers.accessBuffer(
|
m_execBarriers.accessBuffer(
|
||||||
bufferView->getSliceHandle(),
|
bufferView->getSliceHandle(),
|
||||||
stages, access,
|
stages, access,
|
||||||
bufferView->bufferInfo().stages,
|
bufferView->buffer()->info().stages,
|
||||||
bufferView->bufferInfo().access);
|
bufferView->buffer()->info().access);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access);
|
DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access);
|
||||||
|
@ -247,7 +247,7 @@ namespace dxvk {
|
|||||||
m_rc[slot].imageView = nullptr;
|
m_rc[slot].imageView = nullptr;
|
||||||
|
|
||||||
if (view != nullptr) {
|
if (view != nullptr) {
|
||||||
m_rc[slot].bufferSlice = view->slice();
|
m_rc[slot].bufferSlice = DxvkBufferSlice(view);
|
||||||
m_rc[slot].bufferView = std::move(view);
|
m_rc[slot].bufferView = std::move(view);
|
||||||
} else {
|
} else {
|
||||||
m_rc[slot].bufferSlice = DxvkBufferSlice();
|
m_rc[slot].bufferSlice = DxvkBufferSlice();
|
||||||
|
@ -164,13 +164,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBufferView> DxvkDevice::createBufferView(
|
|
||||||
const Rc<DxvkBuffer>& buffer,
|
|
||||||
const DxvkBufferViewCreateInfo& createInfo) {
|
|
||||||
return new DxvkBufferView(this, buffer, createInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkImage> DxvkDevice::createImage(
|
Rc<DxvkImage> DxvkDevice::createImage(
|
||||||
const DxvkImageCreateInfo& createInfo,
|
const DxvkImageCreateInfo& createInfo,
|
||||||
VkMemoryPropertyFlags memoryType) {
|
VkMemoryPropertyFlags memoryType) {
|
||||||
|
@ -311,18 +311,7 @@ namespace dxvk {
|
|||||||
Rc<DxvkBuffer> createBuffer(
|
Rc<DxvkBuffer> createBuffer(
|
||||||
const DxvkBufferCreateInfo& createInfo,
|
const DxvkBufferCreateInfo& createInfo,
|
||||||
VkMemoryPropertyFlags memoryType);
|
VkMemoryPropertyFlags memoryType);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Creates a buffer view
|
|
||||||
*
|
|
||||||
* \param [in] buffer The buffer to view
|
|
||||||
* \param [in] createInfo Buffer view properties
|
|
||||||
* \returns The buffer view object
|
|
||||||
*/
|
|
||||||
Rc<DxvkBufferView> createBufferView(
|
|
||||||
const Rc<DxvkBuffer>& buffer,
|
|
||||||
const DxvkBufferViewCreateInfo& createInfo);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates an image object
|
* \brief Creates an image object
|
||||||
*
|
*
|
||||||
|
@ -775,7 +775,7 @@ namespace dxvk::hud {
|
|||||||
viewInfo.rangeLength = info.size;
|
viewInfo.rangeLength = info.size;
|
||||||
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
viewInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
|
|
||||||
m_pageMaskView = m_device->createBufferView(m_pageMaskBuffer, viewInfo);
|
m_pageMaskView = m_pageMaskBuffer->createView(viewInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_stats.pageMasks.empty()) {
|
if (!m_stats.pageMasks.empty()) {
|
||||||
|
@ -254,7 +254,7 @@ namespace dxvk::hud {
|
|||||||
info.rangeLength = m_dataBuffer->info().size;
|
info.rangeLength = m_dataBuffer->info().size;
|
||||||
info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
||||||
|
|
||||||
return m_device->createBufferView(m_dataBuffer, info);
|
return m_dataBuffer->createView(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ namespace dxvk::hud {
|
|||||||
info.rangeLength = m_fontBuffer->info().size;
|
info.rangeLength = m_fontBuffer->info().size;
|
||||||
info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
||||||
|
|
||||||
return m_device->createBufferView(m_fontBuffer, info);
|
return m_fontBuffer->createView(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user