mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 18:45:28 +03:00
Rework GPU BufferView to have handle-like semantics
We wanted views to extend the lifetime of the underlying buffers and at the same time preserve all views until the destruction of the buffer to prevent recreation which might be costly in the future when we need `VkBufferView`s of the buffer but also require a centralized list of all views for recreation of the buffer. It also removes the inconsistency between `BufferView*` being returned in `GetXView` in `GraphicsContext`.
This commit is contained in:
parent
fae5332f20
commit
7a5c771f44
@ -171,23 +171,18 @@ namespace skyline::gpu {
|
|||||||
std::memcpy(backing.data() + offset, data.data(), data.size());
|
std::memcpy(backing.data() + offset, data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BufferView> Buffer::GetView(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format) {
|
Buffer::BufferViewStorage::BufferViewStorage(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format) : offset(offset), range(range), format(format) {}
|
||||||
for (auto viewIt{views.begin()}; viewIt != views.end();) {
|
|
||||||
auto view{viewIt->lock()};
|
BufferView Buffer::GetView(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format) {
|
||||||
if (view && view->offset == offset && view->range == range && view->format == format)
|
for (auto &view : views)
|
||||||
return view;
|
if (view.offset == offset && view.range == range && view.format == format)
|
||||||
else if (!view)
|
return BufferView{shared_from_this(), &view};
|
||||||
viewIt = views.erase(viewIt);
|
|
||||||
else
|
views.emplace_back(offset, range, format);
|
||||||
++viewIt;
|
return BufferView{shared_from_this(), &views.back()};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto view{std::make_shared<BufferView>(shared_from_this(), offset, range, format)};
|
BufferView::BufferView(std::shared_ptr<Buffer> buffer, Buffer::BufferViewStorage *view) : buffer(buffer), view(view) {}
|
||||||
views.push_back(view);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferView::BufferView(std::shared_ptr<Buffer> backing, vk::DeviceSize offset, vk::DeviceSize range, vk::Format format) : buffer(std::move(backing)), offset(offset), range(range), format(format) {}
|
|
||||||
|
|
||||||
void BufferView::lock() {
|
void BufferView::lock() {
|
||||||
auto backing{std::atomic_load(&buffer)};
|
auto backing{std::atomic_load(&buffer)};
|
||||||
|
@ -44,7 +44,18 @@ namespace skyline::gpu {
|
|||||||
GpuDirty, //!< The GPU buffer has been modified but the CPU mappings have not been updated
|
GpuDirty, //!< The GPU buffer has been modified but the CPU mappings have not been updated
|
||||||
} dirtyState{DirtyState::CpuDirty}; //!< The state of the CPU mappings with respect to the GPU buffer
|
} dirtyState{DirtyState::CpuDirty}; //!< The state of the CPU mappings with respect to the GPU buffer
|
||||||
|
|
||||||
std::vector<std::weak_ptr<BufferView>> views; //!< BufferView(s) that are backed by this Buffer, used for repointing to a new Buffer on deletion
|
/**
|
||||||
|
* @brief Storage for all metadata about a specific view into the buffer, used to prevent redundant view creation and duplication of VkBufferView(s)
|
||||||
|
*/
|
||||||
|
struct BufferViewStorage {
|
||||||
|
public:
|
||||||
|
vk::DeviceSize offset;
|
||||||
|
vk::DeviceSize range;
|
||||||
|
vk::Format format;
|
||||||
|
|
||||||
|
BufferViewStorage(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format);
|
||||||
|
};
|
||||||
|
std::list<BufferViewStorage> views; //!< BufferViewStorage(s) that are backed by this Buffer, used for storage and repointing to a new Buffer on deletion
|
||||||
|
|
||||||
friend BufferView;
|
friend BufferView;
|
||||||
friend BufferManager;
|
friend BufferManager;
|
||||||
@ -138,8 +149,9 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A cached or newly created view into this buffer with the supplied attributes
|
* @return A cached or newly created view into this buffer with the supplied attributes
|
||||||
|
* @note The buffer **must** be locked prior to calling this
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<BufferView> GetView(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format = {});
|
BufferView GetView(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format = {});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,16 +159,25 @@ namespace skyline::gpu {
|
|||||||
* @note The object **must** be locked prior to accessing any members as values will be mutated
|
* @note The object **must** be locked prior to accessing any members as values will be mutated
|
||||||
* @note This class conforms to the Lockable and BasicLockable C++ named requirements
|
* @note This class conforms to the Lockable and BasicLockable C++ named requirements
|
||||||
*/
|
*/
|
||||||
struct BufferView : public FenceCycleDependency, public std::enable_shared_from_this<BufferView> {
|
struct BufferView {
|
||||||
std::shared_ptr<Buffer> buffer;
|
std::shared_ptr<Buffer> buffer;
|
||||||
vk::DeviceSize offset;
|
Buffer::BufferViewStorage *view;
|
||||||
vk::DeviceSize range;
|
|
||||||
vk::Format format;
|
|
||||||
|
|
||||||
/**
|
BufferView(std::shared_ptr<Buffer> buffer, Buffer::BufferViewStorage *view);
|
||||||
* @note A view must **NOT** be constructed directly, it should always be retrieved using Buffer::GetView
|
|
||||||
*/
|
constexpr BufferView(nullptr_t = nullptr) : buffer(nullptr), view(nullptr) {}
|
||||||
BufferView(std::shared_ptr<Buffer> backing, vk::DeviceSize offset, vk::DeviceSize range, vk::Format format);
|
|
||||||
|
constexpr operator bool() const {
|
||||||
|
return view != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Buffer::BufferViewStorage *operator->() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::shared_ptr<FenceCycleDependency>() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Acquires an exclusive lock on the buffer for the calling thread
|
* @brief Acquires an exclusive lock on the buffer for the calling thread
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
namespace skyline::gpu {
|
namespace skyline::gpu {
|
||||||
BufferManager::BufferManager(GPU &gpu) : gpu(gpu) {}
|
BufferManager::BufferManager(GPU &gpu) : gpu(gpu) {}
|
||||||
|
|
||||||
std::shared_ptr<BufferView> BufferManager::FindOrCreate(const GuestBuffer &guest) {
|
BufferView BufferManager::FindOrCreate(const GuestBuffer &guest) {
|
||||||
auto guestMapping{guest.mappings.front()};
|
auto guestMapping{guest.mappings.front()};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,6 +37,6 @@ namespace skyline::gpu {
|
|||||||
/**
|
/**
|
||||||
* @return A pre-existing or newly created Buffer object which covers the supplied mappings
|
* @return A pre-existing or newly created Buffer object which covers the supplied mappings
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<BufferView> FindOrCreate(const GuestBuffer &guest);
|
BufferView FindOrCreate(const GuestBuffer &guest);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,12 @@ namespace skyline::gpu::interconnect {
|
|||||||
cycle->AttachObject(view->shared_from_this());
|
cycle->AttachObject(view->shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandExecutor::AttachBuffer(BufferView *view) {
|
void CommandExecutor::AttachBuffer(BufferView view) {
|
||||||
auto buffer{view->buffer.get()};
|
auto buffer{view.buffer.get()};
|
||||||
if (!syncBuffers.contains(buffer)) {
|
if (!syncBuffers.contains(buffer)) {
|
||||||
buffer->WaitOnFence();
|
buffer->WaitOnFence();
|
||||||
buffer->cycle = cycle;
|
buffer->cycle = cycle;
|
||||||
cycle->AttachObject(view->shared_from_this());
|
cycle->AttachObject(view);
|
||||||
syncBuffers.emplace(buffer);
|
syncBuffers.emplace(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
* @note The supplied buffer **must** be locked by the calling thread
|
* @note The supplied buffer **must** be locked by the calling thread
|
||||||
* @note This'll automatically handle syncing of the buffer in the most optimal way possible
|
* @note This'll automatically handle syncing of the buffer in the most optimal way possible
|
||||||
*/
|
*/
|
||||||
void AttachBuffer(BufferView *view);
|
void AttachBuffer(BufferView view);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Attach the lifetime of the fence cycle dependency to the command buffer
|
* @brief Attach the lifetime of the fence cycle dependency to the command buffer
|
||||||
|
@ -572,7 +572,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
IOVA iova;
|
IOVA iova;
|
||||||
u32 size;
|
u32 size;
|
||||||
GuestBuffer guest;
|
GuestBuffer guest;
|
||||||
std::shared_ptr<BufferView> view;
|
BufferView view;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads an object from the supplied offset in the constant buffer
|
* @brief Reads an object from the supplied offset in the constant buffer
|
||||||
@ -603,8 +603,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Write(T &object, size_t offset) {
|
void Write(T &object, size_t offset) {
|
||||||
std::lock_guard lock{*view};
|
std::scoped_lock lock{view};
|
||||||
view->buffer->Write(span<T>(object).template cast<u8>(), view->offset + offset);
|
view.buffer->Write(span<T>(object).template cast<u8>(), view->offset + offset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ConstantBuffer constantBufferSelector; //!< The constant buffer selector is used to bind a constant buffer to a stage or update data in it
|
ConstantBuffer constantBufferSelector; //!< The constant buffer selector is used to bind a constant buffer to a stage or update data in it
|
||||||
@ -612,17 +612,17 @@ namespace skyline::gpu::interconnect {
|
|||||||
public:
|
public:
|
||||||
void SetConstantBufferSelectorSize(u32 size) {
|
void SetConstantBufferSelectorSize(u32 size) {
|
||||||
constantBufferSelector.size = size;
|
constantBufferSelector.size = size;
|
||||||
constantBufferSelector.view.reset();
|
constantBufferSelector.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetConstantBufferSelectorIovaHigh(u32 high) {
|
void SetConstantBufferSelectorIovaHigh(u32 high) {
|
||||||
constantBufferSelector.iova.high = high;
|
constantBufferSelector.iova.high = high;
|
||||||
constantBufferSelector.view.reset();
|
constantBufferSelector.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetConstantBufferSelectorIovaLow(u32 low) {
|
void SetConstantBufferSelectorIovaLow(u32 low) {
|
||||||
constantBufferSelector.iova.low = low;
|
constantBufferSelector.iova.low = low;
|
||||||
constantBufferSelector.view.reset();
|
constantBufferSelector.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ConstantBuffer> GetConstantBufferSelector() {
|
std::optional<ConstantBuffer> GetConstantBufferSelector() {
|
||||||
@ -915,13 +915,13 @@ namespace skyline::gpu::interconnect {
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto view{pipelineStage.constantBuffers[constantBuffer.index].view};
|
auto view{pipelineStage.constantBuffers[constantBuffer.index].view};
|
||||||
std::scoped_lock lock(*view);
|
std::scoped_lock lock(view);
|
||||||
bufferInfo.push_back(vk::DescriptorBufferInfo{
|
bufferInfo.push_back(vk::DescriptorBufferInfo{
|
||||||
.buffer = view->buffer->GetBacking(),
|
.buffer = view.buffer->GetBacking(),
|
||||||
.offset = view->offset,
|
.offset = view->offset,
|
||||||
.range = view->range,
|
.range = view->range,
|
||||||
});
|
});
|
||||||
executor.AttachBuffer(view.get());
|
executor.AttachBuffer(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1423,7 +1423,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
vk::VertexInputBindingDescription bindingDescription{};
|
vk::VertexInputBindingDescription bindingDescription{};
|
||||||
vk::VertexInputBindingDivisorDescriptionEXT bindingDivisorDescription{};
|
vk::VertexInputBindingDivisorDescriptionEXT bindingDivisorDescription{};
|
||||||
IOVA start{}, end{}; //!< IOVAs covering a contiguous region in GPU AS with the vertex buffer
|
IOVA start{}, end{}; //!< IOVAs covering a contiguous region in GPU AS with the vertex buffer
|
||||||
std::shared_ptr<BufferView> view;
|
BufferView view;
|
||||||
};
|
};
|
||||||
std::array<VertexBuffer, maxwell3d::VertexBufferCount> vertexBuffers{};
|
std::array<VertexBuffer, maxwell3d::VertexBufferCount> vertexBuffers{};
|
||||||
|
|
||||||
@ -1445,25 +1445,25 @@ namespace skyline::gpu::interconnect {
|
|||||||
void SetVertexBufferStartIovaHigh(u32 index, u32 high) {
|
void SetVertexBufferStartIovaHigh(u32 index, u32 high) {
|
||||||
auto &vertexBuffer{vertexBuffers[index]};
|
auto &vertexBuffer{vertexBuffers[index]};
|
||||||
vertexBuffer.start.high = high;
|
vertexBuffer.start.high = high;
|
||||||
vertexBuffer.view.reset();
|
vertexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVertexBufferStartIovaLow(u32 index, u32 low) {
|
void SetVertexBufferStartIovaLow(u32 index, u32 low) {
|
||||||
auto &vertexBuffer{vertexBuffers[index]};
|
auto &vertexBuffer{vertexBuffers[index]};
|
||||||
vertexBuffer.start.low = low;
|
vertexBuffer.start.low = low;
|
||||||
vertexBuffer.view.reset();
|
vertexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVertexBufferEndIovaHigh(u32 index, u32 high) {
|
void SetVertexBufferEndIovaHigh(u32 index, u32 high) {
|
||||||
auto &vertexBuffer{vertexBuffers[index]};
|
auto &vertexBuffer{vertexBuffers[index]};
|
||||||
vertexBuffer.end.high = high;
|
vertexBuffer.end.high = high;
|
||||||
vertexBuffer.view.reset();
|
vertexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVertexBufferEndIovaLow(u32 index, u32 low) {
|
void SetVertexBufferEndIovaLow(u32 index, u32 low) {
|
||||||
auto &vertexBuffer{vertexBuffers[index]};
|
auto &vertexBuffer{vertexBuffers[index]};
|
||||||
vertexBuffer.end.low = low;
|
vertexBuffer.end.low = low;
|
||||||
vertexBuffer.view.reset();
|
vertexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVertexBufferDivisor(u32 index, u32 divisor) {
|
void SetVertexBufferDivisor(u32 index, u32 divisor) {
|
||||||
@ -1578,19 +1578,19 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferView *GetVertexBuffer(size_t index) {
|
BufferView GetVertexBuffer(size_t index) {
|
||||||
auto &vertexBuffer{vertexBuffers.at(index)};
|
auto &vertexBuffer{vertexBuffers.at(index)};
|
||||||
if (vertexBuffer.start > vertexBuffer.end || vertexBuffer.start == 0 || vertexBuffer.end == 0)
|
if (vertexBuffer.start > vertexBuffer.end || vertexBuffer.start == 0 || vertexBuffer.end == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (vertexBuffer.view)
|
else if (vertexBuffer.view)
|
||||||
return vertexBuffer.view.get();
|
return vertexBuffer.view;
|
||||||
|
|
||||||
GuestBuffer guest;
|
GuestBuffer guest;
|
||||||
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(vertexBuffer.start, (vertexBuffer.end + 1) - vertexBuffer.start)};
|
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(vertexBuffer.start, (vertexBuffer.end + 1) - vertexBuffer.start)};
|
||||||
guest.mappings.assign(mappings.begin(), mappings.end());
|
guest.mappings.assign(mappings.begin(), mappings.end());
|
||||||
|
|
||||||
vertexBuffer.view = gpu.buffer.FindOrCreate(guest);
|
vertexBuffer.view = gpu.buffer.FindOrCreate(guest);
|
||||||
return vertexBuffer.view.get();
|
return vertexBuffer.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input Assembly */
|
/* Input Assembly */
|
||||||
@ -1638,7 +1638,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
IOVA start{}, end{}; //!< IOVAs covering a contiguous region in GPU AS containing the index buffer (end does not represent the true extent of the index buffers, just a maximum possible extent and is set to extremely high values which cannot be used to create a buffer)
|
IOVA start{}, end{}; //!< IOVAs covering a contiguous region in GPU AS containing the index buffer (end does not represent the true extent of the index buffers, just a maximum possible extent and is set to extremely high values which cannot be used to create a buffer)
|
||||||
vk::IndexType type{};
|
vk::IndexType type{};
|
||||||
vk::DeviceSize viewSize{}; //!< The size of the cached view
|
vk::DeviceSize viewSize{}; //!< The size of the cached view
|
||||||
std::shared_ptr<BufferView> view{}; //!< A cached view tied to the IOVAs and size to allow for a faster lookup
|
BufferView view{}; //!< A cached view tied to the IOVAs and size to allow for a faster lookup
|
||||||
|
|
||||||
vk::DeviceSize GetIndexBufferSize(u32 elementCount) {
|
vk::DeviceSize GetIndexBufferSize(u32 elementCount) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -2120,22 +2120,22 @@ namespace skyline::gpu::interconnect {
|
|||||||
public:
|
public:
|
||||||
void SetIndexBufferStartIovaHigh(u32 high) {
|
void SetIndexBufferStartIovaHigh(u32 high) {
|
||||||
indexBuffer.start.high = high;
|
indexBuffer.start.high = high;
|
||||||
indexBuffer.view.reset();
|
indexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexBufferStartIovaLow(u32 low) {
|
void SetIndexBufferStartIovaLow(u32 low) {
|
||||||
indexBuffer.start.low = low;
|
indexBuffer.start.low = low;
|
||||||
indexBuffer.view.reset();
|
indexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexBufferEndIovaHigh(u32 high) {
|
void SetIndexBufferEndIovaHigh(u32 high) {
|
||||||
indexBuffer.end.high = high;
|
indexBuffer.end.high = high;
|
||||||
indexBuffer.view.reset();
|
indexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexBufferEndIovaLow(u32 low) {
|
void SetIndexBufferEndIovaLow(u32 low) {
|
||||||
indexBuffer.end.low = low;
|
indexBuffer.end.low = low;
|
||||||
indexBuffer.view.reset();
|
indexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndexBufferFormat(maxwell3d::IndexBuffer::Format format) {
|
void SetIndexBufferFormat(maxwell3d::IndexBuffer::Format format) {
|
||||||
@ -2155,22 +2155,22 @@ namespace skyline::gpu::interconnect {
|
|||||||
if (indexBuffer.type == vk::IndexType::eUint8EXT && !gpu.traits.supportsUint8Indices)
|
if (indexBuffer.type == vk::IndexType::eUint8EXT && !gpu.traits.supportsUint8Indices)
|
||||||
throw exception("Cannot use U8 index buffer without host GPU support");
|
throw exception("Cannot use U8 index buffer without host GPU support");
|
||||||
|
|
||||||
indexBuffer.view.reset();
|
indexBuffer.view = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferView *GetIndexBuffer(u32 elementCount) {
|
BufferView GetIndexBuffer(u32 elementCount) {
|
||||||
auto size{indexBuffer.GetIndexBufferSize(elementCount)};
|
auto size{indexBuffer.GetIndexBufferSize(elementCount)};
|
||||||
if (indexBuffer.start > indexBuffer.end || indexBuffer.start == 0 || indexBuffer.end == 0 || size == 0)
|
if (indexBuffer.start > indexBuffer.end || indexBuffer.start == 0 || indexBuffer.end == 0 || size == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (indexBuffer.view && size == indexBuffer.viewSize)
|
else if (indexBuffer.view && size == indexBuffer.viewSize)
|
||||||
return indexBuffer.view.get();
|
return indexBuffer.view;
|
||||||
|
|
||||||
GuestBuffer guestBuffer;
|
GuestBuffer guestBuffer;
|
||||||
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(indexBuffer.start, size)};
|
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(indexBuffer.start, size)};
|
||||||
guestBuffer.mappings.assign(mappings.begin(), mappings.end());
|
guestBuffer.mappings.assign(mappings.begin(), mappings.end());
|
||||||
|
|
||||||
indexBuffer.view = gpu.buffer.FindOrCreate(guestBuffer);
|
indexBuffer.view = gpu.buffer.FindOrCreate(guestBuffer);
|
||||||
return indexBuffer.view.get();
|
return indexBuffer.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Depth */
|
/* Depth */
|
||||||
@ -2391,10 +2391,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
vk::IndexType indexBufferType;
|
vk::IndexType indexBufferType;
|
||||||
if constexpr (IsIndexed) {
|
if constexpr (IsIndexed) {
|
||||||
auto indexBufferView{GetIndexBuffer(count)};
|
auto indexBufferView{GetIndexBuffer(count)};
|
||||||
std::scoped_lock lock(*indexBufferView);
|
std::scoped_lock lock(indexBufferView);
|
||||||
executor.AttachBuffer(indexBufferView);
|
executor.AttachBuffer(indexBufferView);
|
||||||
|
|
||||||
indexBufferHandle = indexBufferView->buffer->GetBacking();
|
indexBufferHandle = indexBufferView.buffer->GetBacking();
|
||||||
indexBufferOffset = indexBufferView->offset;
|
indexBufferOffset = indexBufferView->offset;
|
||||||
indexBufferType = indexBuffer.type;
|
indexBufferType = indexBuffer.type;
|
||||||
}
|
}
|
||||||
@ -2414,8 +2414,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
if (vertexBuffer.bindingDescription.inputRate == vk::VertexInputRate::eInstance)
|
if (vertexBuffer.bindingDescription.inputRate == vk::VertexInputRate::eInstance)
|
||||||
vertexBindingDivisorsDescriptions.push_back(vertexBuffer.bindingDivisorDescription);
|
vertexBindingDivisorsDescriptions.push_back(vertexBuffer.bindingDivisorDescription);
|
||||||
|
|
||||||
std::scoped_lock vertexBufferLock(*vertexBufferView);
|
std::scoped_lock vertexBufferLock(vertexBufferView);
|
||||||
vertexBufferHandles[index] = vertexBufferView->buffer->GetBacking();
|
vertexBufferHandles[index] = vertexBufferView.buffer->GetBacking();
|
||||||
vertexBufferOffsets[index] = vertexBufferView->offset;
|
vertexBufferOffsets[index] = vertexBufferView->offset;
|
||||||
executor.AttachBuffer(vertexBufferView);
|
executor.AttachBuffer(vertexBufferView);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user