mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-27 19:44:15 +01:00
vk_shader_decompiler: Implement Layer output attribute
SPIR-V's Layer is GLSL's gl_Layer. It lets the application choose from a shader stage (vertex, tessellation or geometry) which framebuffer layer write the output fragments to.
This commit is contained in:
parent
f552d553ba
commit
1caf3f11c8
@ -86,6 +86,7 @@ struct AttributeType {
|
|||||||
|
|
||||||
struct VertexIndices {
|
struct VertexIndices {
|
||||||
std::optional<u32> position;
|
std::optional<u32> position;
|
||||||
|
std::optional<u32> layer;
|
||||||
std::optional<u32> viewport;
|
std::optional<u32> viewport;
|
||||||
std::optional<u32> point_size;
|
std::optional<u32> point_size;
|
||||||
std::optional<u32> clip_distances;
|
std::optional<u32> clip_distances;
|
||||||
@ -282,9 +283,11 @@ public:
|
|||||||
AddExtension("SPV_KHR_storage_buffer_storage_class");
|
AddExtension("SPV_KHR_storage_buffer_storage_class");
|
||||||
AddExtension("SPV_KHR_variable_pointers");
|
AddExtension("SPV_KHR_variable_pointers");
|
||||||
|
|
||||||
if (ir.UsesViewportIndex()) {
|
if (ir.UsesLayer() || ir.UsesViewportIndex()) {
|
||||||
AddCapability(spv::Capability::MultiViewport);
|
if (ir.UsesViewportIndex()) {
|
||||||
if (device.IsExtShaderViewportIndexLayerSupported()) {
|
AddCapability(spv::Capability::MultiViewport);
|
||||||
|
}
|
||||||
|
if (stage != ShaderType::Geometry && device.IsExtShaderViewportIndexLayerSupported()) {
|
||||||
AddExtension("SPV_EXT_shader_viewport_index_layer");
|
AddExtension("SPV_EXT_shader_viewport_index_layer");
|
||||||
AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
|
AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
|
||||||
}
|
}
|
||||||
@ -920,13 +923,22 @@ private:
|
|||||||
VertexIndices indices;
|
VertexIndices indices;
|
||||||
indices.position = AddBuiltIn(t_float4, spv::BuiltIn::Position, "position");
|
indices.position = AddBuiltIn(t_float4, spv::BuiltIn::Position, "position");
|
||||||
|
|
||||||
|
if (ir.UsesLayer()) {
|
||||||
|
if (stage != ShaderType::Vertex || device.IsExtShaderViewportIndexLayerSupported()) {
|
||||||
|
indices.layer = AddBuiltIn(t_int, spv::BuiltIn::Layer, "layer");
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(
|
||||||
|
Render_Vulkan,
|
||||||
|
"Shader requires Layer but it's not supported on this stage with this device.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ir.UsesViewportIndex()) {
|
if (ir.UsesViewportIndex()) {
|
||||||
if (stage != ShaderType::Vertex || device.IsExtShaderViewportIndexLayerSupported()) {
|
if (stage != ShaderType::Vertex || device.IsExtShaderViewportIndexLayerSupported()) {
|
||||||
indices.viewport = AddBuiltIn(t_int, spv::BuiltIn::ViewportIndex, "viewport_index");
|
indices.viewport = AddBuiltIn(t_int, spv::BuiltIn::ViewportIndex, "viewport_index");
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Render_Vulkan,
|
LOG_ERROR(Render_Vulkan, "Shader requires ViewportIndex but it's not supported on "
|
||||||
"Shader requires ViewportIndex but it's not supported on this "
|
"this stage with this device.");
|
||||||
"stage with this device.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1285,6 +1297,13 @@ private:
|
|||||||
}
|
}
|
||||||
case Attribute::Index::LayerViewportPointSize:
|
case Attribute::Index::LayerViewportPointSize:
|
||||||
switch (element) {
|
switch (element) {
|
||||||
|
case 1: {
|
||||||
|
if (!out_indices.layer) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const u32 index = out_indices.layer.value();
|
||||||
|
return {AccessElement(t_out_int, out_vertex, index), Type::Int};
|
||||||
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
if (!out_indices.viewport) {
|
if (!out_indices.viewport) {
|
||||||
return {};
|
return {};
|
||||||
@ -1355,6 +1374,11 @@ private:
|
|||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!target.id) {
|
||||||
|
// On failure we return a nullptr target.id, skip these stores.
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
OpStore(target.id, As(Visit(src), target.type));
|
OpStore(target.id, As(Visit(src), target.type));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user