|
|
@ -212,6 +212,20 @@ Id TextureColorResultType(EmitContext& ctx, const TextureDefinition& def) { |
|
|
throw InvalidArgument("Invalid sampler component type {}", def.component_type); |
|
|
throw InvalidArgument("Invalid sampler component type {}", def.component_type); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Id TextureSampleResultToFloat(EmitContext& ctx, const TextureDefinition& def, Id color) { |
|
|
|
|
|
switch (def.component_type) { |
|
|
|
|
|
case SamplerComponentType::Float: |
|
|
|
|
|
case SamplerComponentType::Depth: |
|
|
|
|
|
return color; |
|
|
|
|
|
case SamplerComponentType::Sint: |
|
|
|
|
|
case SamplerComponentType::Stencil: |
|
|
|
|
|
return ctx.OpConvertSToF(ctx.F32[4], color); |
|
|
|
|
|
case SamplerComponentType::Uint: |
|
|
|
|
|
return ctx.OpConvertUToF(ctx.F32[4], color); |
|
|
|
|
|
} |
|
|
|
|
|
throw InvalidArgument("Invalid sampler component type {}", def.component_type); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) { |
|
|
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) { |
|
|
if (!index.IsImmediate() || index.U32() != 0) { |
|
|
if (!index.IsImmediate() || index.U32() != 0) { |
|
|
throw NotImplementedException("Indirect image indexing"); |
|
|
throw NotImplementedException("Indirect image indexing"); |
|
|
@ -469,22 +483,24 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& |
|
|
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; |
|
|
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; |
|
|
const Id color_type{TextureColorResultType(ctx, def)}; |
|
|
const Id color_type{TextureColorResultType(ctx, def)}; |
|
|
const Id texture{Texture(ctx, info, index)}; |
|
|
const Id texture{Texture(ctx, info, index)}; |
|
|
|
|
|
Id color{}; |
|
|
if (ctx.stage == Stage::Fragment) { |
|
|
if (ctx.stage == Stage::Fragment) { |
|
|
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, |
|
|
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, |
|
|
bias_lc, offset); |
|
|
bias_lc, offset); |
|
|
return Emit(&EmitContext::OpImageSparseSampleImplicitLod, |
|
|
|
|
|
&EmitContext::OpImageSampleImplicitLod, ctx, inst, color_type, texture, coords, |
|
|
|
|
|
operands.MaskOptional(), operands.Span()); |
|
|
|
|
|
|
|
|
color = Emit(&EmitContext::OpImageSparseSampleImplicitLod, |
|
|
|
|
|
&EmitContext::OpImageSampleImplicitLod, ctx, inst, color_type, texture, |
|
|
|
|
|
coords, operands.MaskOptional(), operands.Span()); |
|
|
} else { |
|
|
} else { |
|
|
// We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as
|
|
|
// We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as
|
|
|
// if the lod was explicitly zero. This may change on Turing with implicit compute
|
|
|
// if the lod was explicitly zero. This may change on Turing with implicit compute
|
|
|
// derivatives
|
|
|
// derivatives
|
|
|
const Id lod{ctx.Const(0.0f)}; |
|
|
const Id lod{ctx.Const(0.0f)}; |
|
|
const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset); |
|
|
const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset); |
|
|
return Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
|
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, texture, coords, |
|
|
|
|
|
operands.Mask(), operands.Span()); |
|
|
|
|
|
|
|
|
color = Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
|
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, texture, |
|
|
|
|
|
coords, operands.Mask(), operands.Span()); |
|
|
} |
|
|
} |
|
|
|
|
|
return TextureSampleResultToFloat(ctx, def, color); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
|
|
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
|
|
@ -493,9 +509,10 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& |
|
|
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; |
|
|
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; |
|
|
const Id color_type{TextureColorResultType(ctx, def)}; |
|
|
const Id color_type{TextureColorResultType(ctx, def)}; |
|
|
const ImageOperands operands(ctx, false, true, false, lod, offset); |
|
|
const ImageOperands operands(ctx, false, true, false, lod, offset); |
|
|
return Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
|
|
|
|
|
|
const Id color{Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, |
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, |
|
|
Texture(ctx, info, index), coords, operands.Mask(), operands.Span()); |
|
|
|
|
|
|
|
|
Texture(ctx, info, index), coords, operands.Mask(), operands.Span())}; |
|
|
|
|
|
return TextureSampleResultToFloat(ctx, def, color); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, |
|
|
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, |
|
|
@ -538,9 +555,11 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id |
|
|
if (ctx.profile.need_gather_subpixel_offset) { |
|
|
if (ctx.profile.need_gather_subpixel_offset) { |
|
|
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords); |
|
|
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords); |
|
|
} |
|
|
} |
|
|
return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, |
|
|
|
|
|
color_type, texture, coords, ctx.Const(info.gather_component), |
|
|
|
|
|
operands.MaskOptional(), operands.Span()); |
|
|
|
|
|
|
|
|
const Id color{ |
|
|
|
|
|
Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, color_type, |
|
|
|
|
|
texture, coords, ctx.Const(info.gather_component), operands.MaskOptional(), |
|
|
|
|
|
operands.Span())}; |
|
|
|
|
|
return TextureSampleResultToFloat(ctx, def, color); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
|
|
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
|
|
@ -570,9 +589,13 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c |
|
|
lod = Id{}; |
|
|
lod = Id{}; |
|
|
} |
|
|
} |
|
|
const ImageOperands operands(lod, ms); |
|
|
const ImageOperands operands(lod, ms); |
|
|
return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, |
|
|
|
|
|
|
|
|
Id color{Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, |
|
|
result_type, TextureImage(ctx, info, index), coords, operands.MaskOptional(), |
|
|
result_type, TextureImage(ctx, info, index), coords, operands.MaskOptional(), |
|
|
operands.Span()); |
|
|
|
|
|
|
|
|
operands.Span())}; |
|
|
|
|
|
if (def) { |
|
|
|
|
|
color = TextureSampleResultToFloat(ctx, *def, color); |
|
|
|
|
|
} |
|
|
|
|
|
return color; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod, |
|
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod, |
|
|
@ -624,9 +647,10 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I |
|
|
ctx.Def(offset), {}, lod_clamp) |
|
|
ctx.Def(offset), {}, lod_clamp) |
|
|
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, |
|
|
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, |
|
|
info.num_derivatives, offset, lod_clamp); |
|
|
info.num_derivatives, offset, lod_clamp); |
|
|
return Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
|
|
|
|
|
|
const Id color{Emit(&EmitContext::OpImageSparseSampleExplicitLod, |
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, |
|
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, |
|
|
Texture(ctx, info, index), coords, operands.Mask(), operands.Span()); |
|
|
|
|
|
|
|
|
Texture(ctx, info, index), coords, operands.Mask(), operands.Span())}; |
|
|
|
|
|
return TextureSampleResultToFloat(ctx, def, color); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) { |
|
|
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) { |
|
|
|