Skip to content

Commit

Permalink
specialization: Fix fetch shader field type (shadps4-emu#1675)
Browse files Browse the repository at this point in the history
  • Loading branch information
squidbus authored Dec 6, 2024
1 parent 17abbcd commit d05846a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
13 changes: 0 additions & 13 deletions src/shader_recompiler/frontend/fetch_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,6 @@ struct FetchShaderData {
}) != attributes.end();
}

[[nodiscard]] std::pair<u32, u32> GetDrawOffsets(const AmdGpu::Liverpool::Regs& regs,
const Info& info) const {
u32 vertex_offset = regs.index_offset;
u32 instance_offset = 0;
if (vertex_offset == 0 && vertex_offset_sgpr != -1) {
vertex_offset = info.user_data[vertex_offset_sgpr];
}
if (instance_offset_sgpr != -1) {
instance_offset = info.user_data[instance_offset_sgpr];
}
return {vertex_offset, instance_offset};
}

bool operator==(const FetchShaderData& other) const {
return attributes == other.attributes && vertex_offset_sgpr == other.vertex_offset_sgpr &&
instance_offset_sgpr == other.instance_offset_sgpr;
Expand Down
19 changes: 9 additions & 10 deletions src/shader_recompiler/specialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct StageSpecialization {

const Shader::Info* info;
RuntimeInfo runtime_info;
Gcn::FetchShaderData fetch_shader_data{};
std::optional<Gcn::FetchShaderData> fetch_shader_data{};
boost::container::small_vector<VsAttribSpecialization, 32> vs_attribs;
std::bitset<MaxStageResources> bitset{};
boost::container::small_vector<BufferSpecialization, 16> buffers;
Expand All @@ -69,15 +69,14 @@ struct StageSpecialization {
explicit StageSpecialization(const Info& info_, RuntimeInfo runtime_info_,
const Profile& profile_, Backend::Bindings start_)
: info{&info_}, runtime_info{runtime_info_}, start{start_} {
if (const auto fetch_shader = Gcn::ParseFetchShader(info_)) {
fetch_shader_data = *fetch_shader;
if (info_.stage == Stage::Vertex && !profile_.support_legacy_vertex_attributes) {
// Specialize shader on VS input number types to follow spec.
ForEachSharp(vs_attribs, fetch_shader_data.attributes,
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
spec.num_class = AmdGpu::GetNumberClass(sharp.GetNumberFmt());
});
}
fetch_shader_data = Gcn::ParseFetchShader(info_);
if (info_.stage == Stage::Vertex && fetch_shader_data &&
!profile_.support_legacy_vertex_attributes) {
// Specialize shader on VS input number types to follow spec.
ForEachSharp(vs_attribs, fetch_shader_data->attributes,
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
spec.num_class = AmdGpu::GetNumberClass(sharp.GetNumberFmt());
});
}
u32 binding{};
if (info->has_readconst) {
Expand Down
2 changes: 2 additions & 0 deletions src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ bool PipelineCache::RefreshGraphicsKey() {
++remapped_cb;
}

fetch_shader = std::nullopt;

Shader::Backend::Bindings binding{};
const auto& TryBindStageRemap = [&](Shader::Stage stage_in, Shader::Stage stage_out) -> bool {
const auto stage_in_idx = static_cast<u32>(stage_in);
Expand Down
18 changes: 17 additions & 1 deletion src/video_core/renderer_vulkan/vk_rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ RenderState Rasterizer::PrepareRenderState(u32 mrt_mask) {
return state;
}

[[nodiscard]] std::pair<u32, u32> GetDrawOffsets(
const AmdGpu::Liverpool::Regs& regs, const Shader::Info& info,
const std::optional<Shader::Gcn::FetchShaderData>& fetch_shader) {
u32 vertex_offset = regs.index_offset;
u32 instance_offset = 0;
if (fetch_shader) {
if (vertex_offset == 0 && fetch_shader->vertex_offset_sgpr != -1) {
vertex_offset = info.user_data[fetch_shader->vertex_offset_sgpr];
}
if (fetch_shader->instance_offset_sgpr != -1) {
instance_offset = info.user_data[fetch_shader->instance_offset_sgpr];
}
}
return {vertex_offset, instance_offset};
}

void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
RENDERER_TRACE;

Expand Down Expand Up @@ -198,7 +214,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
BeginRendering(*pipeline, state);
UpdateDynamicState(*pipeline);

const auto [vertex_offset, instance_offset] = fetch_shader->GetDrawOffsets(regs, vs_info);
const auto [vertex_offset, instance_offset] = GetDrawOffsets(regs, vs_info, fetch_shader);

const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->Handle());
Expand Down

0 comments on commit d05846a

Please sign in to comment.