【问题标题】:warning X4000: use of potentially uninitialized variable警告 X4000:使用可能未初始化的变量
【发布时间】:2019-09-01 18:30:38
【问题描述】:

HLSL 编译器发出错误消息“警告 X4000:使用可能未初始化的变量”,代码如下:

float4 GetPixelColorFromRawImage(
    in ByteAddressBuffer Source,
    in uint2             SourceSize,
    in uint2             XY)
{
    // Check if within range
    if (any(XY >= SourceSize))
        return float4(0.5, 0.0, 0.0, 1.0);  // <<<==== WARNING HERE

    if (BytesPerPixel == 3) {
        // 24 bits RGB color image
        uint4 RGBA = GetPixelRGBAFromRawImage(Source, SourceSize, XY);
        return float4(RGBA.r / 256.0,
                      RGBA.g / 256.0,
                      RGBA.b / 256.0,
                      RGBA.a / 256.0);
    }
    else if (BytesPerPixel == 2) {
        // 16 bit grayscale image
        uint  Gray1 = GetPixel16BitGrayFromRawImage(Source, SourceSize, XY);
        uint  Gray2 = GetByteFromUInt(LUT16.Load(Gray1 & (~3)), Gray1 & 3);
        float Gray3 = (float)Gray2 / 256.0;
        return float4(Gray3, Gray3, Gray3, 1.0);
    }
    else {
        return float4(0.0, 0.0, 0.0, 1.0);
    }
}

我不明白那个警告。违规行中根本没有使用任何变量!

任何帮助表示赞赏。

【问题讨论】:

  • any(XY &gt;= SourceSize) 看起来很可疑,为什么要检查布尔值位?
  • @VTT if 运算符需要单个组件布尔值。比较多个组件变量会返回多个组件布尔值,您可以使用 any()all() 将其转换为单个组件布尔值。

标签: directx hlsl directcompute


【解决方案1】:

编译器有时会因为中间的return 调用而发疯,并在不应该出现的地方给出错误。

您可以尝试一些解决方法。

在方法的开头,定义并实例化一个变量,然后在 ifs 中更新它并返回它。

float4 GetPixelColorFromRawImage(
    in ByteAddressBuffer Source,
    in uint2             SourceSize,
    in uint2             XY)
{
    float4 returnVar = float4(0.0, 0.0, 0.0, 0.0);
    // Check if within range
    if (any(XY >= SourceSize))
        returnVar = float4(0.5, 0.0, 0.0, 1.0);  

    if (BytesPerPixel == 3) {
        // 24 bits RGB color image
        uint4 RGBA = GetPixelRGBAFromRawImage(Source, SourceSize, XY);
        returnVar = float4(RGBA.r / 256.0,
                      RGBA.g / 256.0,
                      RGBA.b / 256.0,
                      RGBA.a / 256.0);
        }
    else if (BytesPerPixel == 2) {
        // 16 bit grayscale image
        uint  Gray1 = GetPixel16BitGrayFromRawImage(Source, SourceSize, XY);
        uint  Gray2 = GetByteFromUInt(LUT16.Load(Gray1 & (~3)), Gray1 & 3);
        float Gray3 = (float)Gray2 / 256.0;
        returnVar = float4(Gray3, Gray3, Gray3, 1.0);
        }
    else {
        returnVar = float4(0.0, 0.0, 0.0, 1.0);
        }
    return returnVar;
}

【讨论】:

  • 我从 iPad 发布,无法检查我的代码,如果有错别字,请告诉我,以便我更正(或在我的回答中自行更正)
  • 如您所说,它使用中间变量工作。我将您的答案标记为已接受。非常感谢。
  • 太好了,我很高兴能帮上忙。顺便说一句,我看到你没有接受前两个问题的答案。我想知道他们是否对您没有帮助,以及您是否决定以其他(更好的)方式做事......正如您所见,计算着色器不是您获得数千人的地方,如果您已经找到了更好的方法,这可能对我有启发。
  • 我已接受之前问题的回答。如果我错过了一个,请告诉我是哪个。学习直接计算并不容易,有很多陷阱,编译器对于像我这样的初学者 [在 HLSL 中] 有奇怪的行为。谢谢你的帮助!
  • 我同意,GPGPU 一点也不简单。毕竟,考虑到我们将 GPU 用于它不应该做的事情......部分困难在于文档很少,而且很少有人这样做,而能够做到这一点的人通常会保守秘密,因为它是一种小众工作......而且它被其他编码人员认为是一种魔法:D
猜你喜欢
  • 1970-01-01
  • 2016-07-07
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 2015-03-22
相关资源
最近更新 更多