glasm: Implement stores to gl_ViewportIndex

This commit is contained in:
ReinUsesLisp 2021-05-19 16:32:03 -03:00 committed by ameerj
parent 2494dbe183
commit accad56ee7
4 changed files with 29 additions and 7 deletions

View File

@ -23,7 +23,8 @@ std::string_view InterpDecorator(Interpolation interp) {
} }
} // Anonymous namespace } // Anonymous namespace
EmitContext::EmitContext(IR::Program& program, Bindings& bindings) : info{program.info} { EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_)
: info{program.info}, profile{profile_} {
// FIXME: Temporary partial implementation // FIXME: Temporary partial implementation
u32 cbuf_index{}; u32 cbuf_index{};
for (const auto& desc : program.info.constant_buffer_descriptors) { for (const auto& desc : program.info.constant_buffer_descriptors) {
@ -41,6 +42,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings) : info{progra
if (const size_t num = program.info.storage_buffers_descriptors.size(); num > 0) { if (const size_t num = program.info.storage_buffers_descriptors.size(); num > 0) {
Add("PARAM c[{}]={{program.local[0..{}]}};", num, num - 1); Add("PARAM c[{}]={{program.local[0..{}]}};", num, num - 1);
} }
stage = program.stage;
switch (program.stage) { switch (program.stage) {
case Stage::VertexA: case Stage::VertexA:
case Stage::VertexB: case Stage::VertexB:

View File

@ -11,10 +11,12 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "shader_recompiler/backend/glasm/reg_alloc.h" #include "shader_recompiler/backend/glasm/reg_alloc.h"
#include "shader_recompiler/stage.h"
namespace Shader { namespace Shader {
struct Info; struct Info;
} struct Profile;
} // namespace Shader
namespace Shader::Backend { namespace Shader::Backend {
struct Bindings; struct Bindings;
@ -29,7 +31,7 @@ namespace Shader::Backend::GLASM {
class EmitContext { class EmitContext {
public: public:
explicit EmitContext(IR::Program& program, Bindings& bindings); explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_);
template <typename... Args> template <typename... Args>
void Add(const char* format_str, IR::Inst& inst, Args&&... args) { void Add(const char* format_str, IR::Inst& inst, Args&&... args) {
@ -55,10 +57,12 @@ public:
std::string code; std::string code;
RegAlloc reg_alloc{*this}; RegAlloc reg_alloc{*this};
const Info& info; const Info& info;
const Profile& profile;
std::vector<u32> texture_buffer_bindings; std::vector<u32> texture_buffer_bindings;
std::vector<u32> texture_bindings; std::vector<u32> texture_bindings;
Stage stage{};
std::string_view stage_name = "invalid"; std::string_view stage_name = "invalid";
}; };

View File

@ -261,7 +261,10 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
} }
} }
void SetupOptions(std::string& header, Info info) { void SetupOptions(const IR::Program& program, const Profile& profile, std::string& header) {
const Info& info{program.info};
const Stage stage{program.stage};
// TODO: Track the shared atomic ops // TODO: Track the shared atomic ops
header += "OPTION NV_internal;" header += "OPTION NV_internal;"
"OPTION NV_shader_storage_buffer;" "OPTION NV_shader_storage_buffer;"
@ -286,6 +289,11 @@ void SetupOptions(std::string& header, Info info) {
if (info.uses_sparse_residency) { if (info.uses_sparse_residency) {
header += "OPTION EXT_sparse_texture2;"; header += "OPTION EXT_sparse_texture2;";
} }
if ((info.stores_viewport_index || info.stores_layer) && stage != Stage::Geometry) {
if (profile.support_viewport_index_layer_non_geometry) {
header += "OPTION NV_viewport_array2;";
}
}
const auto non_zero_frag_colors{info.stores_frag_color | std::views::drop(1)}; const auto non_zero_frag_colors{info.stores_frag_color | std::views::drop(1)};
if (std::ranges::find(non_zero_frag_colors, true) != non_zero_frag_colors.end()) { if (std::ranges::find(non_zero_frag_colors, true) != non_zero_frag_colors.end()) {
header += "OPTION ARB_draw_buffers;"; header += "OPTION ARB_draw_buffers;";
@ -312,12 +320,12 @@ std::string_view StageHeader(Stage stage) {
} }
} // Anonymous namespace } // Anonymous namespace
std::string EmitGLASM(const Profile&, IR::Program& program, Bindings& bindings) { std::string EmitGLASM(const Profile& profile, IR::Program& program, Bindings& bindings) {
EmitContext ctx{program, bindings}; EmitContext ctx{program, bindings, profile};
Precolor(ctx, program); Precolor(ctx, program);
EmitCode(ctx, program); EmitCode(ctx, program);
std::string header{StageHeader(program.stage)}; std::string header{StageHeader(program.stage)};
SetupOptions(header, program.info); SetupOptions(program, profile, header);
switch (program.stage) { switch (program.stage) {
case Stage::Compute: case Stage::Compute:
header += fmt::format("GROUP_SIZE {} {} {};", program.workgroup_size[0], header += fmt::format("GROUP_SIZE {} {} {};", program.workgroup_size[0],

View File

@ -7,6 +7,7 @@
#include "shader_recompiler/backend/glasm/emit_context.h" #include "shader_recompiler/backend/glasm/emit_context.h"
#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
#include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/frontend/ir/value.h"
#include "shader_recompiler/profile.h"
namespace Shader::Backend::GLASM { namespace Shader::Backend::GLASM {
namespace { namespace {
@ -102,6 +103,13 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value,
case IR::Attribute::PositionW: case IR::Attribute::PositionW:
ctx.Add("MOV.F result.position.{},{};", swizzle, value); ctx.Add("MOV.F result.position.{},{};", swizzle, value);
break; break;
case IR::Attribute::ViewportIndex:
if (ctx.stage == Stage::Geometry || ctx.profile.support_viewport_index_layer_non_geometry) {
ctx.Add("MOV.F result.viewport.x,{};", value);
} else {
// LOG_WARNING
}
break;
default: default:
throw NotImplementedException("Set attribute {}", attr); throw NotImplementedException("Set attribute {}", attr);
} }