mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 00:44:17 +01:00
Use ConstantBuffer
instead of BufferView
for Shader Constant Buffers
We want read semantics inside the constant buffer object via the mappings to avoid a pointless GPU VMM mapping lookup. It is a fairly frequent operation so this is necessary, the ability to write directly will be added in the future as well.
This commit is contained in:
parent
adb0a16873
commit
d9a9e52350
@ -520,6 +520,29 @@ namespace skyline::gpu::interconnect {
|
|||||||
u32 size;
|
u32 size;
|
||||||
GuestBuffer guest;
|
GuestBuffer guest;
|
||||||
std::shared_ptr<BufferView> view;
|
std::shared_ptr<BufferView> view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads an object from the supplied offset in the constant buffer
|
||||||
|
* @note This must only be called when the GuestBuffer is resolved correctly
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T Read(size_t offset) {
|
||||||
|
T object;
|
||||||
|
size_t objectOffset{};
|
||||||
|
for (auto &mapping: guest.mappings) {
|
||||||
|
if (offset < mapping.size_bytes()) {
|
||||||
|
auto copySize{std::min(mapping.size_bytes() - offset, sizeof(T))};
|
||||||
|
std::memcpy(reinterpret_cast<u8 *>(&object) + objectOffset, mapping.data() + offset, copySize);
|
||||||
|
objectOffset += copySize;
|
||||||
|
if (objectOffset == sizeof(T))
|
||||||
|
return object;
|
||||||
|
offset = mapping.size_bytes();
|
||||||
|
} else {
|
||||||
|
offset -= mapping.size_bytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw exception("Object extent ({} + {} = {}) is larger than constant buffer size: {}", size + offset, sizeof(T), size + offset + sizeof(T), size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
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
|
||||||
|
|
||||||
@ -539,17 +562,17 @@ namespace skyline::gpu::interconnect {
|
|||||||
constantBufferSelector.view.reset();
|
constantBufferSelector.view.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferView *GetConstantBufferSelectorView() {
|
std::optional<ConstantBuffer> GetConstantBufferSelector() {
|
||||||
if (constantBufferSelector.size == 0)
|
if (constantBufferSelector.size == 0)
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
else if (constantBufferSelector.view)
|
else if (constantBufferSelector.view)
|
||||||
return &*constantBufferSelector.view;
|
return constantBufferSelector;
|
||||||
|
|
||||||
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(constantBufferSelector.iova, constantBufferSelector.size)};
|
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(constantBufferSelector.iova, constantBufferSelector.size)};
|
||||||
constantBufferSelector.guest.mappings.assign(mappings.begin(), mappings.end());
|
constantBufferSelector.guest.mappings.assign(mappings.begin(), mappings.end());
|
||||||
|
|
||||||
constantBufferSelector.view = gpu.buffer.FindOrCreate(constantBufferSelector.guest);
|
constantBufferSelector.view = gpu.buffer.FindOrCreate(constantBufferSelector.guest);
|
||||||
return constantBufferSelector.view.get();
|
return constantBufferSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shader Program */
|
/* Shader Program */
|
||||||
@ -622,7 +645,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
u32 bindingBase{}, bindingLast{}; //!< The base and last binding for descriptors bound to this stage
|
u32 bindingBase{}, bindingLast{}; //!< The base and last binding for descriptors bound to this stage
|
||||||
std::optional<vk::raii::ShaderModule> vkModule;
|
std::optional<vk::raii::ShaderModule> vkModule;
|
||||||
|
|
||||||
std::array<std::shared_ptr<BufferView>, maxwell3d::PipelineStageConstantBufferCount> constantBuffers{};
|
std::array<ConstantBuffer, maxwell3d::PipelineStageConstantBufferCount> constantBuffers{};
|
||||||
|
|
||||||
PipelineStage(vk::ShaderStageFlagBits vkStage) : vkStage(vkStage) {}
|
PipelineStage(vk::ShaderStageFlagBits vkStage) : vkStage(vkStage) {}
|
||||||
};
|
};
|
||||||
@ -818,7 +841,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
.stageFlags = pipelineStage.vkStage,
|
.stageFlags = pipelineStage.vkStage,
|
||||||
});
|
});
|
||||||
|
|
||||||
auto view{pipelineStage.constantBuffers[constantBuffer.index]};
|
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(),
|
||||||
@ -878,12 +901,12 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BindPipelineConstantBuffer(maxwell3d::PipelineStage stage, bool enable, u32 index) {
|
void BindPipelineConstantBuffer(maxwell3d::PipelineStage stage, bool enable, u32 index) {
|
||||||
auto &constantBufferView{pipelineStages[stage].constantBuffers[index]};
|
auto &constantBuffer{pipelineStages[stage].constantBuffers[index]};
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
constantBufferView = GetConstantBufferSelectorView()->shared_from_this();
|
constantBuffer = GetConstantBufferSelector().value();
|
||||||
} else {
|
} else {
|
||||||
constantBufferView = nullptr;
|
constantBuffer = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user