glsl: Implement ImageGradient and other texture function variants
This commit is contained in:
		| @@ -100,7 +100,7 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | ||||
|                                 [[maybe_unused]] const IR::Value& offset) { | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("Lod clamp samples"); | ||||
|         throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | ||||
| @@ -108,8 +108,12 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | ||||
|     const auto sparse_inst{PrepareSparse(inst)}; | ||||
|     if (!sparse_inst) { | ||||
|         if (!offset.IsEmpty()) { | ||||
|             ctx.Add("{}=textureOffset({},{},{}{});", texel, texture, coords, | ||||
|                     CastToIntVec(ctx.var_alloc.Consume(offset), info), bias); | ||||
|             const auto offset_str{CastToIntVec(ctx.var_alloc.Consume(offset), info)}; | ||||
|             if (ctx.stage == Stage::Fragment) { | ||||
|                 ctx.Add("{}=textureOffset({},{},{}{});", texel, texture, coords, offset_str, bias); | ||||
|             } else { | ||||
|                 ctx.Add("{}=textureLodOffset({},{},0.0,{});", texel, texture, coords, offset_str); | ||||
|             } | ||||
|         } else { | ||||
|             if (ctx.stage == Stage::Fragment) { | ||||
|                 ctx.Add("{}=texture({},{}{});", texel, texture, coords, bias); | ||||
| @@ -137,10 +141,10 @@ void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | ||||
|                                 [[maybe_unused]] const IR::Value& offset) { | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     if (info.has_bias) { | ||||
|         throw NotImplementedException("Bias texture samples"); | ||||
|         throw NotImplementedException("EmitImageSampleExplicitLod Bias texture samples"); | ||||
|     } | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("Lod clamp samples"); | ||||
|         throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | ||||
| @@ -175,26 +179,34 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     const auto sparse_inst{PrepareSparse(inst)}; | ||||
|     if (sparse_inst) { | ||||
|         throw NotImplementedException("Sparse texture samples"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefImplicitLod Sparse texture samples"); | ||||
|     } | ||||
|     if (info.has_bias) { | ||||
|         throw NotImplementedException("Bias texture samples"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefImplicitLod Bias texture samples"); | ||||
|     } | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("Lod clamp samples"); | ||||
|     } | ||||
|     if (!offset.IsEmpty()) { | ||||
|         throw NotImplementedException("textureLodOffset"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | ||||
|     const auto cast{ShadowSamplerVecCast(info.type)}; | ||||
|     if (!offset.IsEmpty()) { | ||||
|         const auto offset_str{CastToIntVec(ctx.var_alloc.Consume(offset), info)}; | ||||
|         if (ctx.stage == Stage::Fragment) { | ||||
|             ctx.AddF32("{}=textureOffset({},{}({},{}),{}{});", inst, texture, cast, coords, dref, | ||||
|                        offset_str, bias); | ||||
|         } else { | ||||
|             ctx.AddF32("{}=textureLodOffset({},{}({},{}),0.0,{});", inst, texture, cast, coords, | ||||
|                        dref, offset_str); | ||||
|         } | ||||
|     } else { | ||||
|         if (ctx.stage == Stage::Fragment) { | ||||
|             ctx.AddF32("{}=texture({},{}({},{}){});", inst, texture, cast, coords, dref, bias); | ||||
|         } else { | ||||
|             ctx.AddF32("{}=textureLod({},{}({},{}),0.0);", inst, texture, cast, coords, dref); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | ||||
|                                     [[maybe_unused]] IR::Inst& inst, | ||||
| @@ -206,24 +218,32 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     const auto sparse_inst{PrepareSparse(inst)}; | ||||
|     if (sparse_inst) { | ||||
|         throw NotImplementedException("Sparse texture samples"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefExplicitLod Sparse texture samples"); | ||||
|     } | ||||
|     if (info.has_bias) { | ||||
|         throw NotImplementedException("Bias texture samples"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefExplicitLod Bias texture samples"); | ||||
|     } | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("Lod clamp samples"); | ||||
|     } | ||||
|     if (!offset.IsEmpty()) { | ||||
|         throw NotImplementedException("textureLodOffset"); | ||||
|         throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     if (!offset.IsEmpty()) { | ||||
|         const auto offset_str{CastToIntVec(ctx.var_alloc.Consume(offset), info)}; | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|             ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc, | ||||
|                        offset_str); | ||||
|         } else { | ||||
|             ctx.AddF32("{}=textureLodOffset({},vec3({},{}),{},{});", inst, texture, coords, dref, | ||||
|                        lod_lc, offset_str); | ||||
|         } | ||||
|     } else { | ||||
|         if (info.type == TextureType::ColorArrayCube) { | ||||
|             ctx.AddF32("{}=textureLod({},{},{},{});", inst, texture, coords, dref, lod_lc); | ||||
|         } else { | ||||
|             ctx.AddF32("{}=textureLod({},vec3({},{}),{});", inst, texture, coords, dref, lod_lc); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitImageGather([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||
|                      [[maybe_unused]] const IR::Value& index, | ||||
| @@ -316,10 +336,10 @@ void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | ||||
|                     [[maybe_unused]] std::string_view ms) { | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     if (info.has_bias) { | ||||
|         throw NotImplementedException("Bias texture samples"); | ||||
|         throw NotImplementedException("EmitImageFetch Bias texture samples"); | ||||
|     } | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("Lod clamp samples"); | ||||
|         throw NotImplementedException("EmitImageFetch Lod clamp samples"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto sparse_inst{PrepareSparse(inst)}; | ||||
| @@ -368,7 +388,7 @@ void EmitImageQueryDimensions([[maybe_unused]] EmitContext& ctx, [[maybe_unused] | ||||
|             "{}=uvec4(uvec3(textureSize({},int({}))),uint(textureQueryLevels({})));", inst, texture, | ||||
|             lod, texture); | ||||
|     case TextureType::Buffer: | ||||
|         throw NotImplementedException("Texture buffers"); | ||||
|         throw NotImplementedException("EmitImageQueryDimensions Texture buffers"); | ||||
|     } | ||||
|     throw LogicError("Unspecified image type {}", info.type.Value()); | ||||
| } | ||||
| @@ -384,10 +404,31 @@ void EmitImageQueryLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | ||||
| void EmitImageGradient([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||
|                        [[maybe_unused]] const IR::Value& index, | ||||
|                        [[maybe_unused]] std::string_view coords, | ||||
|                        [[maybe_unused]] std::string_view derivates, | ||||
|                        [[maybe_unused]] std::string_view offset, | ||||
|                        [[maybe_unused]] std::string_view lod_clamp) { | ||||
|     NotImplemented(); | ||||
|                        [[maybe_unused]] const IR::Value& derivatives, | ||||
|                        [[maybe_unused]] const IR::Value& offset, | ||||
|                        [[maybe_unused]] const IR::Value& lod_clamp) { | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     if (info.has_lod_clamp) { | ||||
|         throw NotImplementedException("EmitImageGradient Lod clamp samples"); | ||||
|     } | ||||
|     const auto sparse_inst{PrepareSparse(inst)}; | ||||
|     if (sparse_inst) { | ||||
|         throw NotImplementedException("EmitImageGradient Sparse"); | ||||
|     } | ||||
|     if (!offset.IsEmpty()) { | ||||
|         throw NotImplementedException("EmitImageGradient offset"); | ||||
|     } | ||||
|     const auto texture{Texture(ctx, info, index)}; | ||||
|     const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | ||||
|     const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; | ||||
|     const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; | ||||
|     if (multi_component) { | ||||
|         ctx.Add("{}=textureGrad({},{},vec2({}.xz),vec2({}.yz));", texel, texture, coords, | ||||
|                 derivatives_vec, derivatives_vec); | ||||
|     } else { | ||||
|         ctx.Add("{}=textureGrad({},{},float({}.x),float({}.y));", texel, texture, coords, | ||||
|                 derivatives_vec, derivatives_vec); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||
|   | ||||
| @@ -631,8 +631,8 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value& | ||||
| void EmitImageQueryLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                        std::string_view coords); | ||||
| void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                        std::string_view coords, std::string_view derivates, std::string_view offset, | ||||
|                        std::string_view lod_clamp); | ||||
|                        std::string_view coords, const IR::Value& derivatives, | ||||
|                        const IR::Value& offset, const IR::Value& lod_clamp); | ||||
| void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                    std::string_view coords); | ||||
| void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user