spirv: Implement Layer stores

This commit is contained in:
ReinUsesLisp 2021-04-14 18:09:18 -03:00 committed by ameerj
parent ab3831f6cb
commit d8ec99dada
6 changed files with 30 additions and 9 deletions

View file

@ -1050,8 +1050,15 @@ void EmitContext::DefineOutputs(const Info& info) {
const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; const Id type{TypeArray(F32[1], Constant(U32[1], 8U))};
clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); 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 && 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) { if (stage == Stage::Fragment) {
throw NotImplementedException("Storing ViewportIndex in fragment stage"); throw NotImplementedException("Storing ViewportIndex in fragment stage");
} }

View file

@ -157,6 +157,7 @@ public:
Id front_face{}; Id front_face{};
Id point_coord{}; Id point_coord{};
Id clip_distances{}; Id clip_distances{};
Id layer{};
Id viewport_index{}; Id viewport_index{};
Id fswzadd_lut_a{}; Id fswzadd_lut_a{};

View file

@ -124,17 +124,17 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size()); const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
spv::ExecutionModel execution_model{}; spv::ExecutionModel execution_model{};
switch (program.stage) { switch (program.stage) {
case Shader::Stage::Compute: { case Stage::Compute: {
const std::array<u32, 3> workgroup_size{program.workgroup_size}; const std::array<u32, 3> workgroup_size{program.workgroup_size};
execution_model = spv::ExecutionModel::GLCompute; execution_model = spv::ExecutionModel::GLCompute;
ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0], ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0],
workgroup_size[1], workgroup_size[2]); workgroup_size[1], workgroup_size[2]);
break; break;
} }
case Shader::Stage::VertexB: case Stage::VertexB:
execution_model = spv::ExecutionModel::Vertex; execution_model = spv::ExecutionModel::Vertex;
break; break;
case Shader::Stage::Geometry: case Stage::Geometry:
execution_model = spv::ExecutionModel::Geometry; execution_model = spv::ExecutionModel::Geometry;
ctx.AddCapability(spv::Capability::Geometry); ctx.AddCapability(spv::Capability::Geometry);
ctx.AddCapability(spv::Capability::GeometryStreams); 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::OutputVertices, program.output_vertices);
ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, program.invocations); ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, program.invocations);
break; break;
case Shader::Stage::Fragment: case Stage::Fragment:
execution_model = spv::ExecutionModel::Fragment; execution_model = spv::ExecutionModel::Fragment;
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
if (program.info.stores_frag_depth) { 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.AddExtension("SPV_EXT_demote_to_helper_invocation");
ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
} }
if (info.stores_layer) {
ctx.AddCapability(spv::Capability::ShaderLayer);
}
if (info.stores_viewport_index) { if (info.stores_viewport_index) {
ctx.AddCapability(spv::Capability::MultiViewport); 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.AddExtension("SPV_EXT_shader_viewport_index_layer");
ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
} }

View file

@ -76,9 +76,14 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
const Id clip_num{ctx.Constant(ctx.U32[1], index)}; const Id clip_num{ctx.Constant(ctx.U32[1], index)};
return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); 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: case IR::Attribute::ViewportIndex:
return (ctx.profile.support_viewport_index_layer_non_geometry || return ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry) ctx.stage == Shader::Stage::Geometry
? std::optional<Id>{ctx.viewport_index} ? std::optional<Id>{ctx.viewport_index}
: std::nullopt; : std::nullopt;
default: default:

View file

@ -83,6 +83,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) {
case IR::Attribute::ClipDistance7: case IR::Attribute::ClipDistance7:
info.stores_clip_distance = true; info.stores_clip_distance = true;
break; break;
case IR::Attribute::Layer:
info.stores_layer = true;
break;
case IR::Attribute::ViewportIndex: case IR::Attribute::ViewportIndex:
info.stores_viewport_index = true; info.stores_viewport_index = true;
break; break;

View file

@ -109,6 +109,7 @@ struct Info {
bool stores_position{}; bool stores_position{};
bool stores_point_size{}; bool stores_point_size{};
bool stores_clip_distance{}; bool stores_clip_distance{};
bool stores_layer{};
bool stores_viewport_index{}; bool stores_viewport_index{};
bool stores_indexed_attributes{}; bool stores_indexed_attributes{};