graphics: consume vertex semantics directly from shader metadata

This commit is contained in:
nmzik 2026-09-29 04:27:37 +04:00
parent 6d6666819a
commit e57c37fa9c
4 changed files with 18 additions and 22 deletions

View File

@ -371,16 +371,15 @@ static void ShaderDetectBuffers(ShaderVertexInputInfo& info) {
} }
static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info, static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
const ShaderSemantic* input_semantics, std::span<const ShaderSemantic> input_semantics,
uint32_t num_input_semantics, const uint32_t* attrib, const uint32_t* attrib, const uint32_t* buffer) {
const uint32_t* buffer) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
EXIT_IF(attrib == nullptr || buffer == nullptr); EXIT_IF(attrib == nullptr || buffer == nullptr);
const bool debug_dump = Config::GraphicsDebugDumpEnabled(); const bool debug_dump = Config::GraphicsDebugDumpEnabled();
for (uint32_t i = 0; i < num_input_semantics; i++) { for (uint32_t i = 0; i < input_semantics.size(); i++) {
const auto& in = input_semantics[i]; const auto& in = input_semantics[i];
EXIT_NOT_IMPLEMENTED(in.static_vb_index == 1 || in.static_attribute == 1); EXIT_NOT_IMPLEMENTED(in.static_vb_index == 1 || in.static_attribute == 1);
@ -534,8 +533,7 @@ static bool ShaderGetStaticVertexInputInfo(uint64_t shader_addr, const HW::UserS
shader_addr); shader_addr);
return false; return false;
} }
ShaderApplyAttribSemantics(info, metadata.input_semantics.data(), ShaderApplyAttribSemantics(info, metadata.input_semantics, attrib, buffer);
metadata.input_semantics_count, attrib, buffer);
ShaderDetectBuffers(info); ShaderDetectBuffers(info);
} }
return true; return true;

View File

@ -68,13 +68,10 @@ bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sg
return ShaderError::Fail(error, "vertex semantic count is outside the supported domain"); return ShaderError::Fail(error, "vertex semantic count is outside the supported domain");
} }
const auto semantic_size =
static_cast<uint64_t>(data.num_input_semantics) * sizeof(ShaderSemantic);
if (data.input_semantics == nullptr) { if (data.input_semantics == nullptr) {
return ShaderError::Fail(error, "missing vertex input semantics"); return ShaderError::Fail(error, "missing vertex input semantics");
} }
std::memcpy(next.input_semantics.data(), data.input_semantics, semantic_size); next.input_semantics = {data.input_semantics, data.num_input_semantics};
next.input_semantics_count = data.num_input_semantics;
metadata = next; metadata = next;
return true; return true;
} }

View File

@ -3,19 +3,18 @@
#include "graphics/shader/shader.h" #include "graphics/shader/shader.h"
#include <array> #include <span>
#include <string> #include <string>
namespace Libs::Graphics { namespace Libs::Graphics {
struct ShaderVertexMetadata { struct ShaderVertexMetadata {
int vertex_buffer_reg = -1; int vertex_buffer_reg = -1;
int vertex_attrib_reg = -1; int vertex_attrib_reg = -1;
std::array<ShaderSemantic, ShaderVertexInputInfo::RES_MAX> input_semantics {}; std::span<const ShaderSemantic> input_semantics;
uint32_t input_semantics_count = 0;
}; };
// Copies the small AGC metadata subset used by the vertex path after validating every guest range. // Validates the vertex metadata and returns a view into the shader header.
bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sgprs, bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sgprs,
ShaderVertexMetadata& metadata, std::string* error); ShaderVertexMetadata& metadata, std::string* error);

View File

@ -36,14 +36,16 @@ struct Fixture {
void CheckRejected(const ShaderMappedData& data, const char* text) { void CheckRejected(const ShaderMappedData& data, const char* text) {
ShaderVertexMetadata output; ShaderVertexMetadata output;
output.vertex_buffer_reg = 37; std::array<ShaderSemantic, 7> prior_semantics {};
output.vertex_attrib_reg = 41; output.vertex_buffer_reg = 37;
output.input_semantics_count = 7; output.vertex_attrib_reg = 41;
output.input_semantics = prior_semantics;
std::string error; std::string error;
Check(!ShaderReadVertexMetadata(data, 64, output, &error), text); Check(!ShaderReadVertexMetadata(data, 64, output, &error), text);
Check(!error.empty(), "metadata rejection omitted its diagnostic"); Check(!error.empty(), "metadata rejection omitted its diagnostic");
Check(output.vertex_buffer_reg == 37 && output.vertex_attrib_reg == 41 && Check(output.vertex_buffer_reg == 37 && output.vertex_attrib_reg == 41 &&
output.input_semantics_count == 7, output.input_semantics.data() == prior_semantics.data() &&
output.input_semantics.size() == prior_semantics.size(),
"metadata rejection changed the prior output"); "metadata rejection changed the prior output");
} }
@ -54,7 +56,7 @@ void TestValidAndInvalidMetadata() {
Check(ShaderReadVertexMetadata(fixture.mapped, 64, output, &error), Check(ShaderReadVertexMetadata(fixture.mapped, 64, output, &error),
"valid AGC vertex metadata was rejected"); "valid AGC vertex metadata was rejected");
Check(output.vertex_buffer_reg == 2 && output.vertex_attrib_reg == 4 && Check(output.vertex_buffer_reg == 2 && output.vertex_attrib_reg == 4 &&
output.input_semantics_count == 1, output.input_semantics.size() == 1,
"valid AGC vertex metadata was decoded incorrectly"); "valid AGC vertex metadata was decoded incorrectly");
Fixture buffer_only; Fixture buffer_only;
@ -65,7 +67,7 @@ void TestValidAndInvalidMetadata() {
Check(ShaderReadVertexMetadata(buffer_only.mapped, 64, output, &error), Check(ShaderReadVertexMetadata(buffer_only.mapped, 64, output, &error),
"vertex-buffer-only AGC metadata was rejected"); "vertex-buffer-only AGC metadata was rejected");
Check(output.vertex_buffer_reg == 2 && output.vertex_attrib_reg == -1 && Check(output.vertex_buffer_reg == 2 && output.vertex_attrib_reg == -1 &&
output.input_semantics_count == 0, output.input_semantics.empty(),
"vertex-buffer-only AGC metadata was decoded incorrectly"); "vertex-buffer-only AGC metadata was decoded incorrectly");
Fixture attrib_only; Fixture attrib_only;