glasm: Implement stores to gl_ViewportIndex
This commit is contained in:
parent
2494dbe183
commit
accad56ee7
|
@ -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:
|
||||||
|
|
|
@ -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";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue