mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
graphics: hoist loop-invariant checks out of draw/attrib hot paths (#807)
* graphics: hoist loop-invariant checks out of draw/attrib hot paths DrawIndirectMulti recomputed the index_type_and_size switch on every sub-draw of a multi-draw-indirect call, and ShaderApplyAttribSemantics re-checked the debug-dump config flag on every vertex attribute. Both values are invariant across their respective loops, so compute them once before iterating instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * graphics: cache vertex buffer descriptor size in AcquireVertexBuffers VertexBufferDescriptorSize was computed twice per vertex-buffer slot on every draw call: once while collecting guest ranges, and again while rebuilding slot bindings. Both calls use identical inputs, so cache the first pass's result and reuse it in the second. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -976,6 +976,16 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun
|
|||||||
const auto args_size = indexed ? sizeof(DrawIndexedIndirectArgs) : sizeof(DrawIndirectArgs);
|
const auto args_size = indexed ? sizeof(DrawIndexedIndirectArgs) : sizeof(DrawIndirectArgs);
|
||||||
EXIT_NOT_IMPLEMENTED(stride_in_bytes < args_size);
|
EXIT_NOT_IMPLEMENTED(stride_in_bytes < args_size);
|
||||||
|
|
||||||
|
uint64_t index_size = 0;
|
||||||
|
if (indexed) {
|
||||||
|
switch (m_index_type_and_size) {
|
||||||
|
case 0: index_size = 2; break;
|
||||||
|
case 1: index_size = 4; break;
|
||||||
|
case 2: index_size = 1; break;
|
||||||
|
default: EXIT("unknown index_type_and_size: %u\n", m_index_type_and_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < draw_count; i++) {
|
for (uint32_t i = 0; i < draw_count; i++) {
|
||||||
const auto args_addr = m_draw_indirect_args_base_addr + data_offset +
|
const auto args_addr = m_draw_indirect_args_base_addr + data_offset +
|
||||||
static_cast<uint64_t>(i) * stride_in_bytes;
|
static_cast<uint64_t>(i) * stride_in_bytes;
|
||||||
@@ -993,14 +1003,6 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun
|
|||||||
|
|
||||||
auto* args = reinterpret_cast<const DrawIndexedIndirectArgs*>(args_addr);
|
auto* args = reinterpret_cast<const DrawIndexedIndirectArgs*>(args_addr);
|
||||||
|
|
||||||
uint64_t index_size = 0;
|
|
||||||
switch (m_index_type_and_size) {
|
|
||||||
case 0: index_size = 2; break;
|
|
||||||
case 1: index_size = 4; break;
|
|
||||||
case 2: index_size = 1; break;
|
|
||||||
default: EXIT("unknown index_type_and_size: %u\n", m_index_type_and_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* index_addr = reinterpret_cast<const void*>(
|
auto* index_addr = reinterpret_cast<const void*>(
|
||||||
m_index_base_addr + static_cast<uint64_t>(args->start_index_location) * index_size);
|
m_index_base_addr + static_cast<uint64_t>(args->start_index_location) * index_size);
|
||||||
|
|
||||||
|
|||||||
@@ -686,11 +686,13 @@ static PreparedVertexBuffers AcquireVertexBuffers(CommandBuffer& b
|
|||||||
vs_input_info.buffers_num > ShaderVertexInputInfo::RES_MAX);
|
vs_input_info.buffers_num > ShaderVertexInputInfo::RES_MAX);
|
||||||
|
|
||||||
// Collect the non-empty guest vertex ranges.
|
// Collect the non-empty guest vertex ranges.
|
||||||
|
std::array<uint64_t, ShaderVertexInputInfo::RES_MAX> sizes {};
|
||||||
std::array<VertexBufferRange, ShaderVertexInputInfo::RES_MAX> ranges {};
|
std::array<VertexBufferRange, ShaderVertexInputInfo::RES_MAX> ranges {};
|
||||||
uint32_t range_count = 0;
|
uint32_t range_count = 0;
|
||||||
for (int i = 0; i < vs_input_info.buffers_num; i++) {
|
for (int i = 0; i < vs_input_info.buffers_num; i++) {
|
||||||
const auto& vertex = vs_input_info.buffers[i];
|
const auto& vertex = vs_input_info.buffers[i];
|
||||||
const auto size = VertexBufferDescriptorSize(vertex, vs_input_info);
|
const auto size = VertexBufferDescriptorSize(vertex, vs_input_info);
|
||||||
|
sizes[i] = size;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -739,7 +741,7 @@ static PreparedVertexBuffers AcquireVertexBuffers(CommandBuffer& b
|
|||||||
vk::Buffer null_buffer = nullptr;
|
vk::Buffer null_buffer = nullptr;
|
||||||
for (int i = 0; i < vs_input_info.buffers_num; i++) {
|
for (int i = 0; i < vs_input_info.buffers_num; i++) {
|
||||||
const auto& vertex = vs_input_info.buffers[i];
|
const auto& vertex = vs_input_info.buffers[i];
|
||||||
const auto size = VertexBufferDescriptorSize(vertex, vs_input_info);
|
const auto size = sizes[i];
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
if (null_buffer == nullptr) {
|
if (null_buffer == nullptr) {
|
||||||
null_buffer = cache.GetBuffer(NULL_BUFFER_ID).Handle();
|
null_buffer = cache.GetBuffer(NULL_BUFFER_ID).Handle();
|
||||||
|
|||||||
@@ -388,6 +388,8 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
|
|||||||
|
|
||||||
EXIT_IF(attrib == nullptr || buffer == nullptr);
|
EXIT_IF(attrib == nullptr || buffer == nullptr);
|
||||||
|
|
||||||
|
const bool debug_dump = Config::GraphicsDebugDumpEnabled();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_input_semantics; i++) {
|
for (uint32_t i = 0; i < num_input_semantics; i++) {
|
||||||
const auto& in = input_semantics[i];
|
const auto& in = input_semantics[i];
|
||||||
|
|
||||||
@@ -396,7 +398,7 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
|
|||||||
uint32_t reg = in.hardware_mapping;
|
uint32_t reg = in.hardware_mapping;
|
||||||
uint32_t size = in.size_in_elements;
|
uint32_t size = in.size_in_elements;
|
||||||
|
|
||||||
if (Config::GraphicsDebugDumpEnabled()) {
|
if (debug_dump) {
|
||||||
LOGF("reg = %u, size = %u, va[%u] = 0x%08" PRIx32 "\n", reg, size, i,
|
LOGF("reg = %u, size = %u, va[%u] = 0x%08" PRIx32 "\n", reg, size, i,
|
||||||
attrib[in.semantic]);
|
attrib[in.semantic]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user