glsl: skip gl_ViewportIndex write if device does not support it

master
ameerj 2021-06-02 00:48:49 +07:00
parent f4799e8fa1
commit 6577a63d36
5 changed files with 18 additions and 8 deletions

@ -148,23 +148,24 @@ std::string_view OutputPrimitive(OutputTopology topology) {
throw InvalidArgument("Invalid output topology {}", topology);
}
void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) {
if (!StoresPerVertexAttributes(stage)) {
void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
if (!StoresPerVertexAttributes(ctx.stage)) {
return;
}
header += "out gl_PerVertex{";
header += "vec4 gl_Position;";
if (info.stores_point_size) {
if (ctx.info.stores_point_size) {
header += "float gl_PointSize;";
}
if (info.stores_clip_distance) {
if (ctx.info.stores_clip_distance) {
header += "float gl_ClipDistance[];";
}
if (info.stores_viewport_index && stage != Stage::Geometry) {
if (ctx.info.stores_viewport_index && ctx.supports_viewport_layer &&
ctx.stage != Stage::Geometry) {
header += "int gl_ViewportIndex;";
}
header += "};\n";
if (info.stores_viewport_index && stage == Stage::Geometry) {
if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) {
header += "out int gl_ViewportIndex;";
}
}
@ -173,6 +174,7 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) {
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
const RuntimeInfo& runtime_info_)
: info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
supports_viewport_layer = profile.support_gl_vertex_viewport_layer;
SetupExtensions(header);
stage = program.stage;
switch (program.stage) {
@ -206,7 +208,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
program.workgroup_size[2]);
break;
}
SetupOutPerVertex(stage, info, header);
SetupOutPerVertex(*this, header);
for (size_t index = 0; index < info.input_generics.size(); ++index) {
const auto& generic{info.input_generics[index]};
if (generic.used) {
@ -276,7 +278,7 @@ void EmitContext::SetupExtensions(std::string&) {
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
}
}
if (info.stores_viewport_index && stage != Stage::Geometry) {
if (info.stores_viewport_index && supports_viewport_layer && stage != Stage::Geometry) {
header += "#extension GL_ARB_shader_viewport_layer_array : enable\n";
}
}

@ -159,6 +159,7 @@ public:
bool uses_y_direction{};
bool uses_cc_carry{};
bool supports_viewport_layer{};
private:
void SetupExtensions(std::string& header);

@ -226,6 +226,11 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
ctx.Add("gl_Position.{}={};", swizzle, value);
break;
case IR::Attribute::ViewportIndex:
if (ctx.stage != Stage::Geometry && !ctx.supports_viewport_layer) {
// LOG_WARNING(..., "Shader stores viewport index but device does not support viewport
// layer extension");
break;
}
ctx.Add("gl_ViewportIndex=floatBitsToInt({});", value);
break;
case IR::Attribute::ClipDistance0:

@ -85,6 +85,7 @@ struct Profile {
bool support_derivative_control{};
bool support_gl_nv_gpu_shader_5{};
bool support_gl_amd_gpu_shader_half_float{};
bool support_gl_vertex_viewport_layer{};
bool warp_size_potentially_larger_than_guest{};

@ -225,6 +225,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
.support_derivative_control = device.HasDerivativeControl(),
.support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
.support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
.support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(),
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),