ResourceFormat MakeResourceFormat()

in renderdoc/driver/gl/gl_common.cpp [1872:2322]


ResourceFormat MakeResourceFormat(GLenum target, GLenum fmt)
{
  ResourceFormat ret;

  ret.type = ResourceFormatType::Regular;

  if(fmt == eGL_NONE)
  {
    ret.type = ResourceFormatType::Undefined;
    return ret;
  }

  // special handling for formats that don't query neatly
  if(fmt == eGL_LUMINANCE8_EXT || fmt == eGL_INTENSITY8_EXT || fmt == eGL_LUMINANCE)
  {
    ret.compByteWidth = 1;
    ret.compCount = 1;
    ret.compType = CompType::UNorm;
    return ret;
  }
  else if(fmt == eGL_ALPHA || fmt == eGL_ALPHA8_EXT)
  {
    ret.compByteWidth = 1;
    ret.compCount = 1;
    ret.compType = CompType::UNorm;
    ret.type = ResourceFormatType::A8;
    return ret;
  }
  else if(fmt == eGL_LUMINANCE8_ALPHA8_EXT || fmt == eGL_LUMINANCE_ALPHA)
  {
    ret.compByteWidth = 1;
    ret.compCount = 2;
    ret.compType = CompType::UNorm;
    return ret;
  }
  else if(fmt == eGL_RGBA2)
  {
    // pretend it's RGBA8 and hope for the best
    ret.compByteWidth = 1;
    ret.compCount = 4;
    ret.compType = CompType::UNorm;
    return ret;
  }

  if(IsCompressedFormat(fmt))
  {
    switch(fmt)
    {
      // BC1
      case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: ret.compCount = 3; break;
      case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: ret.compCount = 4; break;

      // BC2
      case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: ret.compCount = 4; break;

      // BC3
      case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: ret.compCount = 4; break;
      // BC4
      case eGL_COMPRESSED_RED_RGTC1:
      case eGL_COMPRESSED_SIGNED_RED_RGTC1: ret.compCount = 1; break;
      // BC5
      case eGL_COMPRESSED_RG_RGTC2:
      case eGL_COMPRESSED_SIGNED_RG_RGTC2: ret.compCount = 2; break;
      // BC6
      case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
      case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: ret.compCount = 3; break;
      // BC7
      case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
      case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: ret.compCount = 4; break;

      case eGL_COMPRESSED_RGBA8_ETC2_EAC:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.compCount = 4; break;
      case eGL_COMPRESSED_R11_EAC:
      case eGL_COMPRESSED_SIGNED_R11_EAC: ret.compCount = 1; break;
      case eGL_COMPRESSED_RG11_EAC:
      case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compCount = 2; break;

      case eGL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
      case eGL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: ret.compCount = 3; break;
      case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: ret.compCount = 4; break;

      case eGL_ETC1_RGB8_OES:
      case eGL_COMPRESSED_RGB8_ETC2:
      case eGL_COMPRESSED_SRGB8_ETC2: ret.compCount = 3; break;
      case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: ret.compCount = 4; break;

      case eGL_COMPRESSED_RGBA_ASTC_4x4_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_5x4_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_5x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_6x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_6x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x8_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x8_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x10_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_12x10_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_12x12_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: ret.compCount = 4; break;

      default: break;
    }

    ret.compType = CompType::UNorm;

    switch(fmt)
    {
      case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
      case eGL_COMPRESSED_SRGB8_ETC2:
      case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.compType = CompType::UNormSRGB; break;
      default: break;
    }

    switch(fmt)
    {
      case eGL_COMPRESSED_SIGNED_RED_RGTC1:
      case eGL_COMPRESSED_SIGNED_RG_RGTC2:
      case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
      case eGL_COMPRESSED_SIGNED_R11_EAC:
      case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compType = CompType::SNorm; break;
      default: break;
    }

    ret.type = ResourceFormatType::Undefined;

    switch(fmt)
    {
      // BC1
      case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: ret.type = ResourceFormatType::BC1; break;
      // BC2
      case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: ret.type = ResourceFormatType::BC2; break;
      // BC3
      case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: ret.type = ResourceFormatType::BC3; break;
      // BC4
      case eGL_COMPRESSED_RED_RGTC1:
      case eGL_COMPRESSED_SIGNED_RED_RGTC1: ret.type = ResourceFormatType::BC4; break;
      // BC5
      case eGL_COMPRESSED_RG_RGTC2:
      case eGL_COMPRESSED_SIGNED_RG_RGTC2: ret.type = ResourceFormatType::BC5; break;
      // BC6
      case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
      case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: ret.type = ResourceFormatType::BC6; break;
      // BC7
      case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
      case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: ret.type = ResourceFormatType::BC7; break;
      // ETC1
      case eGL_ETC1_RGB8_OES:    // handle it as ETC2
      // ETC2
      case eGL_COMPRESSED_RGB8_ETC2:
      case eGL_COMPRESSED_SRGB8_ETC2:
      case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
        ret.type = ResourceFormatType::ETC2;
        break;
      // EAC
      case eGL_COMPRESSED_RGBA8_ETC2_EAC:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
      case eGL_COMPRESSED_R11_EAC:
      case eGL_COMPRESSED_SIGNED_R11_EAC:
      case eGL_COMPRESSED_RG11_EAC:
      case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.type = ResourceFormatType::EAC; break;
      // ASTC
      case eGL_COMPRESSED_RGBA_ASTC_4x4_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_5x4_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_5x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_6x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_6x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_8x8_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x5_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x6_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x8_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_10x10_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_12x10_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_12x12_KHR:
      case eGL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
      case eGL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
      case eGL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
      case eGL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
      case eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES: ret.type = ResourceFormatType::ASTC; break;
      // PVRTC
      case eGL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
      case eGL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
      case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: ret.type = ResourceFormatType::PVRTC; break;
      default: RDCERR("Unexpected compressed format %#x", fmt); break;
    }

    return ret;
  }

  // handle certain non compressed but special formats
  switch(fmt)
  {
    case eGL_R11F_G11F_B10F:
      ret.type = ResourceFormatType::R11G11B10;
      ret.compType = CompType::Float;
      ret.compCount = 3;
      break;
    case eGL_RGB565:
      ret.type = ResourceFormatType::R5G6B5;
      ret.compType = CompType::UNorm;
      ret.compCount = 3;
      ret.SetBGRAOrder(true);
      break;
    case eGL_RGB5_A1:
      ret.type = ResourceFormatType::R5G5B5A1;
      ret.compType = CompType::UNorm;
      ret.compCount = 4;
      ret.SetBGRAOrder(true);
      break;
    case eGL_RGB9_E5:
      ret.type = ResourceFormatType::R9G9B9E5;
      ret.compType = CompType::Float;
      ret.compCount = 3;
      break;
    case eGL_RGBA4:
      ret.type = ResourceFormatType::R4G4B4A4;
      ret.compType = CompType::UNorm;
      ret.compCount = 4;
      ret.SetBGRAOrder(true);
      break;
    case eGL_RGB10_A2:
    case eGL_RGB10_A2UI:
      ret.type = ResourceFormatType::R10G10B10A2;
      ret.compType = fmt == eGL_RGB10_A2 ? CompType::UNorm : CompType::UInt;
      ret.compCount = 4;
      break;
    default: break;
  }

  if(ret.Special())
    return ret;

  ret.compByteWidth = 1;
  ret.compCount = 4;
  ret.compType = CompType::Float;

  GLint data[8];
  GLenum *edata = (GLenum *)data;

  GLint iscol = 0, isdepth = 0, isstencil = 0;
  GL.glGetInternalformativ(target, fmt, eGL_COLOR_COMPONENTS, 1, &iscol);
  GL.glGetInternalformativ(target, fmt, eGL_DEPTH_COMPONENTS, 1, &isdepth);
  GL.glGetInternalformativ(target, fmt, eGL_STENCIL_COMPONENTS, 1, &isstencil);

  if(iscol == GL_TRUE)
  {
    if(fmt == eGL_BGRA8_EXT || fmt == eGL_BGRA)
      ret.SetBGRAOrder(true);

    // colour format

    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_SIZE, 1, &data[0]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_SIZE, 1, &data[1]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_SIZE, 1, &data[2]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_SIZE, 1, &data[3]);

    ret.compCount = 0;
    for(int i = 0; i < 4; i++)
      if(data[i] > 0)
        ret.compCount++;

    for(int i = ret.compCount; i < 4; i++)
      data[i] = data[0];

    if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3])
    {
      ret.compByteWidth = (uint8_t)(data[0] / 8);

      // wasn't a byte format (8, 16, 32)
      if(int32_t(ret.compByteWidth) * 8 != data[0])
      {
        ret.type = ResourceFormatType::Undefined;
        RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
      }
    }
    else
    {
      ret.type = ResourceFormatType::Undefined;
      RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
    }

    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_TYPE, 1, &data[0]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_TYPE, 1, &data[1]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_TYPE, 1, &data[2]);
    GL.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_TYPE, 1, &data[3]);

    for(int i = ret.compCount; i < 4; i++)
      data[i] = data[0];

    if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3])
    {
      switch(edata[0])
      {
        case eGL_UNSIGNED_INT: ret.compType = CompType::UInt; break;
        case eGL_UNSIGNED_BYTE:
        case eGL_UNSIGNED_NORMALIZED: ret.compType = CompType::UNorm; break;
        case eGL_SIGNED_NORMALIZED: ret.compType = CompType::SNorm; break;
        case eGL_FLOAT: ret.compType = CompType::Float; break;
        case eGL_INT: ret.compType = CompType::SInt; break;
        default:
        {
          RDCERR("Unexpected texture type");
          if(ret.compByteWidth == 1)
            ret.compType = CompType::UNorm;
          else
            ret.compType = CompType::Float;
        }
      }
    }
    else
    {
      ret.type = ResourceFormatType::Undefined;
      RDCERR("Unexpected/unhandled non-uniform format: '%s'", ToStr(fmt).c_str());
    }

    GL.glGetInternalformativ(target, fmt, eGL_COLOR_ENCODING, 1, &data[0]);
    if(edata[0] == eGL_SRGB || fmt == eGL_SR8_EXT || fmt == eGL_SRG8_EXT)
      ret.compType = CompType::UNormSRGB;
  }
  else if(isdepth == GL_TRUE || isstencil == GL_TRUE)
  {
    // depth format
    ret.compType = CompType::Depth;

    switch(fmt)
    {
      case eGL_DEPTH_COMPONENT16:
        ret.compByteWidth = 2;
        ret.compCount = 1;
        break;
      case eGL_DEPTH_COMPONENT24:
        ret.compByteWidth = 3;
        ret.compCount = 1;
        break;
      case eGL_DEPTH_COMPONENT:
      case eGL_DEPTH_COMPONENT32:
      case eGL_DEPTH_COMPONENT32F:
        ret.compByteWidth = 4;
        ret.compCount = 1;
        break;
      case eGL_DEPTH24_STENCIL8:
        ret.compByteWidth = 0;
        ret.compCount = 2;
        ret.type = ResourceFormatType::D24S8;
        break;
      case eGL_DEPTH_STENCIL:
      case eGL_DEPTH32F_STENCIL8:
        ret.compByteWidth = 0;
        ret.compCount = 2;
        ret.type = ResourceFormatType::D32S8;
        break;
      case eGL_STENCIL_INDEX:
      case eGL_STENCIL_INDEX8:
        ret.compByteWidth = 1;
        ret.compCount = 1;
        ret.type = ResourceFormatType::S8;
        break;
      default: RDCERR("Unexpected depth or stencil format '%s'", ToStr(fmt).c_str());
    }
  }
  else
  {
    // not colour or depth!
    RDCERR("Unexpected texture type, not colour or depth: '%s'", ToStr(fmt).c_str());
  }

  return ret;
}