spirv: Implement Layer stores
This commit is contained in:
		| @@ -1050,8 +1050,15 @@ void EmitContext::DefineOutputs(const Info& info) { | ||||
|         const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; | ||||
|         clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); | ||||
|     } | ||||
|     if (info.stores_layer && | ||||
|         (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { | ||||
|         if (stage == Stage::Fragment) { | ||||
|             throw NotImplementedException("Storing Layer in fragment stage"); | ||||
|         } | ||||
|         layer = DefineOutput(*this, U32[1], spv::BuiltIn::Layer); | ||||
|     } | ||||
|     if (info.stores_viewport_index && | ||||
|         (profile.support_viewport_index_layer_non_geometry || stage == Shader::Stage::Geometry)) { | ||||
|         (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { | ||||
|         if (stage == Stage::Fragment) { | ||||
|             throw NotImplementedException("Storing ViewportIndex in fragment stage"); | ||||
|         } | ||||
|   | ||||
| @@ -157,6 +157,7 @@ public: | ||||
|     Id front_face{}; | ||||
|     Id point_coord{}; | ||||
|     Id clip_distances{}; | ||||
|     Id layer{}; | ||||
|     Id viewport_index{}; | ||||
|  | ||||
|     Id fswzadd_lut_a{}; | ||||
|   | ||||
| @@ -124,17 +124,17 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | ||||
|     const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size()); | ||||
|     spv::ExecutionModel execution_model{}; | ||||
|     switch (program.stage) { | ||||
|     case Shader::Stage::Compute: { | ||||
|     case Stage::Compute: { | ||||
|         const std::array<u32, 3> workgroup_size{program.workgroup_size}; | ||||
|         execution_model = spv::ExecutionModel::GLCompute; | ||||
|         ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0], | ||||
|                              workgroup_size[1], workgroup_size[2]); | ||||
|         break; | ||||
|     } | ||||
|     case Shader::Stage::VertexB: | ||||
|     case Stage::VertexB: | ||||
|         execution_model = spv::ExecutionModel::Vertex; | ||||
|         break; | ||||
|     case Shader::Stage::Geometry: | ||||
|     case Stage::Geometry: | ||||
|         execution_model = spv::ExecutionModel::Geometry; | ||||
|         ctx.AddCapability(spv::Capability::Geometry); | ||||
|         ctx.AddCapability(spv::Capability::GeometryStreams); | ||||
| @@ -172,7 +172,7 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | ||||
|         ctx.AddExecutionMode(main, spv::ExecutionMode::OutputVertices, program.output_vertices); | ||||
|         ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, program.invocations); | ||||
|         break; | ||||
|     case Shader::Stage::Fragment: | ||||
|     case Stage::Fragment: | ||||
|         execution_model = spv::ExecutionModel::Fragment; | ||||
|         ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); | ||||
|         if (program.info.stores_frag_depth) { | ||||
| @@ -258,10 +258,14 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | ||||
|         ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); | ||||
|         ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); | ||||
|     } | ||||
|     if (info.stores_layer) { | ||||
|         ctx.AddCapability(spv::Capability::ShaderLayer); | ||||
|     } | ||||
|     if (info.stores_viewport_index) { | ||||
|         ctx.AddCapability(spv::Capability::MultiViewport); | ||||
|         if (profile.support_viewport_index_layer_non_geometry && | ||||
|             ctx.stage != Shader::Stage::Geometry) { | ||||
|     } | ||||
|     if (info.stores_layer || info.stores_viewport_index) { | ||||
|         if (profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { | ||||
|             ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | ||||
|             ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | ||||
|         } | ||||
|   | ||||
| @@ -76,9 +76,14 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
|         const Id clip_num{ctx.Constant(ctx.U32[1], index)}; | ||||
|         return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); | ||||
|     } | ||||
|     case IR::Attribute::Layer: | ||||
|         return ctx.profile.support_viewport_index_layer_non_geometry || | ||||
|                        ctx.stage == Shader::Stage::Geometry | ||||
|                    ? std::optional<Id>{ctx.layer} | ||||
|                    : std::nullopt; | ||||
|     case IR::Attribute::ViewportIndex: | ||||
|         return (ctx.profile.support_viewport_index_layer_non_geometry || | ||||
|                 ctx.stage == Shader::Stage::Geometry) | ||||
|         return ctx.profile.support_viewport_index_layer_non_geometry || | ||||
|                        ctx.stage == Shader::Stage::Geometry | ||||
|                    ? std::optional<Id>{ctx.viewport_index} | ||||
|                    : std::nullopt; | ||||
|     default: | ||||
|   | ||||
| @@ -83,6 +83,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) { | ||||
|     case IR::Attribute::ClipDistance7: | ||||
|         info.stores_clip_distance = true; | ||||
|         break; | ||||
|     case IR::Attribute::Layer: | ||||
|         info.stores_layer = true; | ||||
|         break; | ||||
|     case IR::Attribute::ViewportIndex: | ||||
|         info.stores_viewport_index = true; | ||||
|         break; | ||||
|   | ||||
| @@ -109,6 +109,7 @@ struct Info { | ||||
|     bool stores_position{}; | ||||
|     bool stores_point_size{}; | ||||
|     bool stores_clip_distance{}; | ||||
|     bool stores_layer{}; | ||||
|     bool stores_viewport_index{}; | ||||
|     bool stores_indexed_attributes{}; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user