video_core: add vertex_offset to non-indexed draw calls

renamed fetch offset fields
This commit is contained in:
Vinicius Rangel 2024-08-24 11:21:50 -03:00
parent d9ea23badc
commit a5e468af47
No known key found for this signature in database
GPG Key ID: A5B154D904B761D9
5 changed files with 28 additions and 30 deletions

View File

@ -35,7 +35,7 @@ namespace Shader::Gcn {
**/ **/
FetchShaderData ParseFetchShader(const u32* code, u32* out_size) { FetchShaderData ParseFetchShader(const u32* code, u32* out_size) {
std::vector<VertexAttribute> attributes; FetchShaderData data{};
GcnCodeSlice code_slice(code, code + std::numeric_limits<u32>::max()); GcnCodeSlice code_slice(code, code + std::numeric_limits<u32>::max());
GcnDecodeContext decoder; GcnDecodeContext decoder;
@ -46,9 +46,6 @@ FetchShaderData ParseFetchShader(const u32* code, u32* out_size) {
}; };
boost::container::static_vector<VsharpLoad, 16> loads; boost::container::static_vector<VsharpLoad, 16> loads;
s8 fetch_index_sgpr = -1;
s8 fetch_offset_sgpr = -1;
u32 semantic_index = 0; u32 semantic_index = 0;
while (!code_slice.atEnd()) { while (!code_slice.atEnd()) {
const auto inst = decoder.decodeInstruction(code_slice); const auto inst = decoder.decodeInstruction(code_slice);
@ -67,11 +64,11 @@ FetchShaderData ParseFetchShader(const u32* code, u32* out_size) {
const auto vgpr = inst.dst[0].code; const auto vgpr = inst.dst[0].code;
const auto sgpr = s8(inst.src[0].code); const auto sgpr = s8(inst.src[0].code);
switch (vgpr) { switch (vgpr) {
case 0: // V0 is always the index case 0: // V0 is always the vertex offset
fetch_index_sgpr = sgpr; data.vertex_offset_sgpr = sgpr;
break; break;
case 3: // V3 is always the offset case 3: // V3 is always the instance offset
fetch_offset_sgpr = sgpr; data.instance_offset_sgpr = sgpr;
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
@ -87,7 +84,7 @@ FetchShaderData ParseFetchShader(const u32* code, u32* out_size) {
const auto it = std::ranges::find_if( const auto it = std::ranges::find_if(
loads, [&](VsharpLoad& load) { return load.dst_reg == base_sgpr; }); loads, [&](VsharpLoad& load) { return load.dst_reg == base_sgpr; });
auto& attrib = attributes.emplace_back(); auto& attrib = data.attributes.emplace_back();
attrib.semantic = semantic_index++; attrib.semantic = semantic_index++;
attrib.dest_vgpr = inst.src[1].code; attrib.dest_vgpr = inst.src[1].code;
attrib.num_elements = inst.control.mubuf.count; attrib.num_elements = inst.control.mubuf.count;
@ -102,11 +99,7 @@ FetchShaderData ParseFetchShader(const u32* code, u32* out_size) {
} }
} }
return FetchShaderData{ return data;
.attributes = std::move(attributes),
.fetch_index_sgpr = fetch_index_sgpr,
.fetch_offset_sgpr = fetch_offset_sgpr,
};
} }
} // namespace Shader::Gcn } // namespace Shader::Gcn

View File

@ -19,8 +19,8 @@ struct VertexAttribute {
struct FetchShaderData { struct FetchShaderData {
std::vector<VertexAttribute> attributes; std::vector<VertexAttribute> attributes;
s8 fetch_index_sgpr; ///< Read index from VADDR s8 vertex_offset_sgpr = -1; ///< SGPR of vertex offset from VADDR
s8 fetch_offset_sgpr; ///< Read offset from VADDR s8 instance_offset_sgpr = -1; ///< SGPR of instance offset from VADDR
}; };
FetchShaderData ParseFetchShader(const u32* code, u32* out_size); FetchShaderData ParseFetchShader(const u32* code, u32* out_size);

View File

@ -359,8 +359,8 @@ void Translator::EmitFetch(const GcnInst& inst) {
file.WriteRaw<u8>(code, fetch_size); file.WriteRaw<u8>(code, fetch_size);
} }
info.fetch_index_sgpr = fetch_data.fetch_index_sgpr; info.vertex_offset_sgpr = fetch_data.vertex_offset_sgpr;
info.fetch_offset_sgpr = fetch_data.fetch_offset_sgpr; info.instance_offset_sgpr = fetch_data.instance_offset_sgpr;
for (const auto& attrib : fetch_data.attributes) { for (const auto& attrib : fetch_data.attributes) {
const IR::Attribute attr{IR::Attribute::Param0 + attrib.semantic}; const IR::Attribute attr{IR::Attribute::Param0 + attrib.semantic};

View File

@ -175,8 +175,8 @@ struct Info {
AttributeFlags stores{}; AttributeFlags stores{};
boost::container::static_vector<VsOutputMap, 3> vs_outputs; boost::container::static_vector<VsOutputMap, 3> vs_outputs;
s8 fetch_index_sgpr = -1; s8 vertex_offset_sgpr = -1;
s8 fetch_offset_sgpr = -1; s8 instance_offset_sgpr = -1;
BufferResourceList buffers; BufferResourceList buffers;
ImageResourceList images; ImageResourceList images;
@ -213,6 +213,18 @@ struct Info {
std::memcpy(&data, base + dword_offset, sizeof(T)); std::memcpy(&data, base + dword_offset, sizeof(T));
return data; return data;
} }
[[nodiscard]] std::pair<u32, u32> GetDrawOffsets() const noexcept {
u32 vertex_offset = 0;
u32 instance_offset = 0;
if (vertex_offset_sgpr != -1) {
vertex_offset = user_data[vertex_offset_sgpr];
}
if (instance_offset_sgpr != -1) {
instance_offset = user_data[instance_offset_sgpr];
}
return {vertex_offset, instance_offset};
}
}; };
constexpr AmdGpu::Buffer BufferResource::GetVsharp(const Info& info) const noexcept { constexpr AmdGpu::Buffer BufferResource::GetVsharp(const Info& info) const noexcept {

View File

@ -51,24 +51,17 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
BeginRendering(); BeginRendering();
UpdateDynamicState(*pipeline); UpdateDynamicState(*pipeline);
u32 instance_offset = 0; const auto [vertex_offset, instance_offset] = vs_info.GetDrawOffsets();
if (vs_info.fetch_offset_sgpr != -1) {
instance_offset = vs_info.user_data[vs_info.fetch_offset_sgpr];
}
if (is_indexed) { if (is_indexed) {
u32 vertex_offset = 0;
if (vs_info.fetch_index_sgpr != -1) {
vertex_offset = vs_info.user_data[vs_info.fetch_index_sgpr];
}
cmdbuf.drawIndexed(num_indices, regs.num_instances.NumInstances(), 0, s32(vertex_offset), cmdbuf.drawIndexed(num_indices, regs.num_instances.NumInstances(), 0, s32(vertex_offset),
instance_offset); instance_offset);
} else { } else {
const u32 num_vertices = regs.primitive_type == AmdGpu::Liverpool::PrimitiveType::RectList const u32 num_vertices = regs.primitive_type == AmdGpu::Liverpool::PrimitiveType::RectList
? 4 ? 4
: regs.num_indices; : regs.num_indices;
cmdbuf.draw(num_vertices, regs.num_instances.NumInstances(), 0, instance_offset); cmdbuf.draw(num_vertices, regs.num_instances.NumInstances(), vertex_offset,
instance_offset);
} }
} }