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:
		| @@ -86,6 +86,7 @@ struct AttributeType { | ||||
|  | ||||
| struct VertexIndices { | ||||
|     std::optional<u32> position; | ||||
|     std::optional<u32> layer; | ||||
|     std::optional<u32> viewport; | ||||
|     std::optional<u32> point_size; | ||||
|     std::optional<u32> clip_distances; | ||||
| @@ -282,9 +283,11 @@ public: | ||||
|         AddExtension("SPV_KHR_storage_buffer_storage_class"); | ||||
|         AddExtension("SPV_KHR_variable_pointers"); | ||||
|  | ||||
|         if (ir.UsesViewportIndex()) { | ||||
|             AddCapability(spv::Capability::MultiViewport); | ||||
|             if (device.IsExtShaderViewportIndexLayerSupported()) { | ||||
|         if (ir.UsesLayer() || ir.UsesViewportIndex()) { | ||||
|             if (ir.UsesViewportIndex()) { | ||||
|                 AddCapability(spv::Capability::MultiViewport); | ||||
|             } | ||||
|             if (stage != ShaderType::Geometry && device.IsExtShaderViewportIndexLayerSupported()) { | ||||
|                 AddExtension("SPV_EXT_shader_viewport_index_layer"); | ||||
|                 AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | ||||
|             } | ||||
| @@ -920,13 +923,22 @@ private: | ||||
|         VertexIndices indices; | ||||
|         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 (stage != ShaderType::Vertex || device.IsExtShaderViewportIndexLayerSupported()) { | ||||
|                 indices.viewport = AddBuiltIn(t_int, spv::BuiltIn::ViewportIndex, "viewport_index"); | ||||
|             } else { | ||||
|                 LOG_ERROR(Render_Vulkan, | ||||
|                           "Shader requires ViewportIndex but it's not supported on this " | ||||
|                           "stage with this device."); | ||||
|                 LOG_ERROR(Render_Vulkan, "Shader requires ViewportIndex but it's not supported on " | ||||
|                                          "this stage with this device."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -1285,6 +1297,13 @@ private: | ||||
|                 } | ||||
|                 case Attribute::Index::LayerViewportPointSize: | ||||
|                     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: { | ||||
|                         if (!out_indices.viewport) { | ||||
|                             return {}; | ||||
| @@ -1355,6 +1374,11 @@ private: | ||||
|             UNIMPLEMENTED(); | ||||
|         } | ||||
|  | ||||
|         if (!target.id) { | ||||
|             // On failure we return a nullptr target.id, skip these stores. | ||||
|             return {}; | ||||
|         } | ||||
|  | ||||
|         OpStore(target.id, As(Visit(src), target.type)); | ||||
|         return {}; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp