shader: Implement TXQ and fix FragDepth

This commit is contained in:
ReinUsesLisp 2021-03-26 18:45:38 -03:00 committed by ameerj
parent d9c5bd9509
commit 17063d16a3
15 changed files with 264 additions and 21 deletions

View file

@ -244,8 +244,9 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
if (desc.count != 1) {
throw NotImplementedException("Array of textures");
}
const Id type{TypeSampledImage(ImageType(*this, desc))};
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, type)};
const Id image_type{ImageType(*this, desc)};
const Id sampled_type{TypeSampledImage(image_type)};
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, sampled_type)};
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
Decorate(id, spv::Decoration::Binding, binding);
Decorate(id, spv::Decoration::DescriptorSet, 0U);
@ -254,7 +255,8 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
// TODO: Pass count info
textures.push_back(TextureDefinition{
.id{id},
.type{type},
.sampled_type{sampled_type},
.image_type{image_type},
});
}
binding += desc.count;

View file

@ -31,7 +31,8 @@ private:
struct TextureDefinition {
Id id;
Id type;
Id sampled_type;
Id image_type;
};
struct UniformDefinitions {

View file

@ -126,10 +126,10 @@ Id DefineMain(EmitContext& ctx, IR::Program& program) {
return main;
}
void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) {
void DefineEntryPoint(Environment& env, const IR::Program& program, EmitContext& ctx, Id main) {
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
spv::ExecutionModel execution_model{};
switch (env.ShaderStage()) {
switch (program.stage) {
case Shader::Stage::Compute: {
const std::array<u32, 3> workgroup_size{env.WorkgroupSize()};
execution_model = spv::ExecutionModel::GLCompute;
@ -143,6 +143,9 @@ void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) {
case Shader::Stage::Fragment:
execution_model = spv::ExecutionModel::Fragment;
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
if (program.info.stores_frag_depth) {
ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
}
break;
default:
throw NotImplementedException("Stage {}", env.ShaderStage());
@ -235,6 +238,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
}
// TODO: Track this usage
ctx.AddCapability(spv::Capability::ImageGatherExtended);
ctx.AddCapability(spv::Capability::ImageQuery);
}
Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
@ -267,7 +271,7 @@ std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program
u32& binding) {
EmitContext ctx{profile, program, binding};
const Id main{DefineMain(ctx, program)};
DefineEntryPoint(env, ctx, main);
DefineEntryPoint(env, program, ctx, main);
if (profile.support_float_controls) {
ctx.AddExtension("SPV_KHR_float_controls");
SetupDenormControl(profile, program, ctx, main);

View file

@ -343,6 +343,7 @@ Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&);
Id EmitBindlessImageGather(EmitContext&);
Id EmitBindlessImageGatherDref(EmitContext&);
Id EmitBindlessImageFetch(EmitContext&);
Id EmitBindlessImageQueryDimensions(EmitContext&);
Id EmitBoundImageSampleImplicitLod(EmitContext&);
Id EmitBoundImageSampleExplicitLod(EmitContext&);
Id EmitBoundImageSampleDrefImplicitLod(EmitContext&);
@ -350,6 +351,7 @@ Id EmitBoundImageSampleDrefExplicitLod(EmitContext&);
Id EmitBoundImageGather(EmitContext&);
Id EmitBoundImageGatherDref(EmitContext&);
Id EmitBoundImageFetch(EmitContext&);
Id EmitBoundImageQueryDimensions(EmitContext&);
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, Id offset);
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
@ -364,6 +366,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
const IR::Value& offset, const IR::Value& offset2, Id dref);
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
Id lod, Id ms);
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod);
Id EmitVoteAll(EmitContext& ctx, Id pred);
Id EmitVoteAny(EmitContext& ctx, Id pred);
Id EmitVoteEqual(EmitContext& ctx, Id pred);

View file

@ -91,7 +91,15 @@ private:
Id Texture(EmitContext& ctx, const IR::Value& index) {
if (index.IsImmediate()) {
const TextureDefinition def{ctx.textures.at(index.U32())};
return ctx.OpLoad(def.type, def.id);
return ctx.OpLoad(def.sampled_type, def.id);
}
throw NotImplementedException("Indirect texture sample");
}
Id TextureImage(EmitContext& ctx, const IR::Value& index) {
if (index.IsImmediate()) {
const TextureDefinition def{ctx.textures.at(index.U32())};
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
}
throw NotImplementedException("Indirect texture sample");
}
@ -149,6 +157,10 @@ Id EmitBindlessImageFetch(EmitContext&) {
throw LogicError("Unreachable instruction");
}
Id EmitBindlessImageQueryDimensions(EmitContext&) {
throw LogicError("Unreachable instruction");
}
Id EmitBoundImageSampleImplicitLod(EmitContext&) {
throw LogicError("Unreachable instruction");
}
@ -177,6 +189,10 @@ Id EmitBoundImageFetch(EmitContext&) {
throw LogicError("Unreachable instruction");
}
Id EmitBoundImageQueryDimensions(EmitContext&) {
throw LogicError("Unreachable instruction");
}
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, Id offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
@ -241,4 +257,34 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
Texture(ctx, index), coords, operands.Mask(), operands.Span());
}
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const Id image{TextureImage(ctx, index)};
const Id zero{ctx.u32_zero_value};
const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }};
switch (info.type) {
case TextureType::Color1D:
case TextureType::Shadow1D:
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[1], image, lod),
zero, zero, mips());
case TextureType::ColorArray1D:
case TextureType::Color2D:
case TextureType::ColorCube:
case TextureType::ShadowArray1D:
case TextureType::Shadow2D:
case TextureType::ShadowCube:
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod),
zero, mips());
case TextureType::ColorArray2D:
case TextureType::Color3D:
case TextureType::ColorArrayCube:
case TextureType::ShadowArray2D:
case TextureType::Shadow3D:
case TextureType::ShadowArrayCube:
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod),
mips());
}
throw LogicError("Unspecified image type {}", info.type.Value());
}
} // namespace Shader::Backend::SPIRV