diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index 5d03c69c9..7534452a4 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -1750,51 +1750,11 @@ void FillInColors(const EventInfo &ei, VkFormat format, PixelModification &mod) { ResourceFormat fmt = MakeResourceFormat(format); - if(fmt.type == ResourceFormatType::R10G10B10A2 || fmt.type == ResourceFormatType::R11G11B10) - { - for(int p = 0; p < 2; p++) - { - ModificationValue *val = (p == 0 ? &mod.preMod : &mod.postMod); - const PixelHistoryValue *source = (p == 0 ? &ei.premod : &ei.postmod); - uint32_t data; - memcpy(&data, source->color, sizeof(uint32_t)); - Vec4f v; - if(fmt.type == ResourceFormatType::R10G10B10A2) - { - if(fmt.compType == CompType::SNorm) - v = ConvertFromR10G10B10A2SNorm(data); - else - v = ConvertFromR10G10B10A2(data); - } - else - { - Vec3f v3 = ConvertFromR11G11B10(data); - v = Vec4f(v3.x, v3.y, v3.z); - } - memcpy(&val->col.floatValue[0], &v, sizeof(float) * 4); - } - return; - } + FloatVector premod = ConvertComponents(fmt, ei.premod.color); + FloatVector postmod = ConvertComponents(fmt, ei.postmod.color); - for(uint8_t c = 0; c < fmt.compCount; c++) - { - // Special case for alpha component in SRGB format. - if(fmt.SRGBCorrected() && (fmt.compByteWidth == 1) && (c == 3)) - { - mod.preMod.col.floatValue[c] = float(ei.premod.color[3]) / 255.0f; - mod.postMod.col.floatValue[c] = float(ei.postmod.color[3]) / 255.0f; - } - else - { - mod.preMod.col.floatValue[c] = ConvertComponent(fmt, ei.premod.color + c * fmt.compByteWidth); - mod.postMod.col.floatValue[c] = ConvertComponent(fmt, ei.postmod.color + c * fmt.compByteWidth); - } - } - if(fmt.BGRAOrder()) - { - std::swap(mod.preMod.col.floatValue[0], mod.preMod.col.floatValue[2]); - std::swap(mod.postMod.col.floatValue[0], mod.postMod.col.floatValue[2]); - } + memcpy(mod.preMod.col.floatValue, &premod.x, sizeof(premod)); + memcpy(mod.postMod.col.floatValue, &postmod.x, sizeof(postmod)); } rdcarray VulkanReplay::PixelHistory(rdcarray events, diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index cacbf6af2..f3bf5b320 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -219,42 +219,12 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u } else { - ResourceFormat fmt = MakeResourceFormat(attr.format); + FloatVector decoded = ConvertComponents(MakeResourceFormat(attr.format), data.data()); - if(fmt.Special()) - { - switch(fmt.type) - { - case ResourceFormatType::R10G10B10A2: - { - Vec4f decoded; - if(fmt.compType == CompType::SNorm) - decoded = ConvertFromR10G10B10A2SNorm(*(uint32_t *)data.data()); - else - decoded = ConvertFromR10G10B10A2(*(uint32_t *)data.data()); - val.f.x = decoded.x; - val.f.y = decoded.y; - val.f.z = decoded.z; - val.f.w = decoded.w; - break; - } - case ResourceFormatType::R11G11B10: - { - Vec3f decoded = ConvertFromR11G11B10(*(uint32_t *)data.data()); - val.f.x = decoded.x; - val.f.y = decoded.y; - val.f.z = decoded.z; - break; - } - default: - RDCERR("Unexpected resource format %s as vertex buffer input", - ToStr(attr.format).c_str()); - } - } - else - { - memcpy(&val.u.x, data.data(), size); - } + val.f.x = decoded.x; + val.f.y = decoded.y; + val.f.z = decoded.z; + val.f.w = decoded.w; } } diff --git a/renderdoc/maths/formatpacking.cpp b/renderdoc/maths/formatpacking.cpp index 7d5735077..d7bc3e67c 100644 --- a/renderdoc/maths/formatpacking.cpp +++ b/renderdoc/maths/formatpacking.cpp @@ -228,128 +228,169 @@ float ConvertLinearToSRGB(float linear) return 1.055f * powf(linear, 1.0f / 2.4f) - 0.055f; } -float ConvertComponent(const ResourceFormat &fmt, const byte *data) +FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data) { - if(fmt.compByteWidth == 8) - { - // we just downcast - const uint64_t *u64 = (const uint64_t *)data; - const int64_t *i64 = (const int64_t *)data; + FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); - if(fmt.compType == CompType::Double || fmt.compType == CompType::Float) - { - return float(*(const double *)u64); - } - else if(fmt.compType == CompType::UInt || fmt.compType == CompType::UScaled) - { - return float(*u64); - } - else if(fmt.compType == CompType::SInt || fmt.compType == CompType::SScaled) - { - return float(*i64); - } + if(fmt.type == ResourceFormatType::R10G10B10A2) + { + Vec4f v; + if(fmt.compType == CompType::SNorm) + v = ConvertFromR10G10B10A2SNorm(*(const uint32_t *)data); + else + v = ConvertFromR10G10B10A2(*(const uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + ret.w = v.w; } - else if(fmt.compByteWidth == 4) + else if(fmt.type == ResourceFormatType::R11G11B10) { - const uint32_t *u32 = (const uint32_t *)data; - const int32_t *i32 = (const int32_t *)data; - - if(fmt.compType == CompType::Float || fmt.compType == CompType::Depth) - { - return *(const float *)u32; - } - else if(fmt.compType == CompType::UInt || fmt.compType == CompType::UScaled) - { - return float(*u32); - } - else if(fmt.compType == CompType::SInt || fmt.compType == CompType::SScaled) - { - return float(*i32); - } + Vec3f v = ConvertFromR11G11B10(*(const uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; } - else if(fmt.compByteWidth == 3 && fmt.compType == CompType::Depth) + else { - // 24-bit depth is a weird edge case we need to assemble it by hand - const uint8_t *u8 = (const uint8_t *)data; + float *comp = &ret.x; - uint32_t depth = 0; - depth |= uint32_t(u8[1]); - depth |= uint32_t(u8[2]) << 8; - depth |= uint32_t(u8[3]) << 16; + CompType compType = fmt.compType; + for(size_t c = 0; c < fmt.compCount; c++) + { + // alpha is never interpreted as sRGB + if(compType == CompType::UNormSRGB && c == 3) + compType = CompType::UNorm; - return float(depth) / float(16777215.0f); - } - else if(fmt.compByteWidth == 2) - { - const uint16_t *u16 = (const uint16_t *)data; - const int16_t *i16 = (const int16_t *)data; + if(fmt.compByteWidth == 8) + { + // we just downcast + const uint64_t *u64 = (const uint64_t *)data; + const int64_t *i64 = (const int64_t *)data; - if(fmt.compType == CompType::Float) - { - return ConvertFromHalf(*u16); - } - else if(fmt.compType == CompType::UInt || fmt.compType == CompType::UScaled) - { - return float(*u16); - } - else if(fmt.compType == CompType::SInt || fmt.compType == CompType::SScaled) - { - return float(*i16); - } - // 16-bit depth is UNORM - else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::Depth) - { - return float(*u16) / 65535.0f; - } - else if(fmt.compType == CompType::SNorm) - { - float f = -1.0f; + if(compType == CompType::Double || compType == CompType::Float) + { + *comp = float(*(const double *)u64); + } + else if(compType == CompType::UInt || compType == CompType::UScaled) + { + *comp = float(*u64); + } + else if(compType == CompType::SInt || compType == CompType::SScaled) + { + *comp = float(*i64); + } + } + else if(fmt.compByteWidth == 4) + { + const uint32_t *u32 = (const uint32_t *)data; + const int32_t *i32 = (const int32_t *)data; - if(*i16 == -32768) - f = -1.0f; + if(compType == CompType::Float || compType == CompType::Depth) + { + *comp = *(const float *)u32; + } + else if(compType == CompType::UInt || compType == CompType::UScaled) + { + *comp = float(*u32); + } + else if(compType == CompType::SInt || compType == CompType::SScaled) + { + *comp = float(*i32); + } + } + else if(fmt.compByteWidth == 3 && compType == CompType::Depth) + { + // 24-bit depth is a weird edge case we need to assemble it by hand + const uint8_t *u8 = (const uint8_t *)data; + + uint32_t depth = 0; + depth |= uint32_t(u8[1]); + depth |= uint32_t(u8[2]) << 8; + depth |= uint32_t(u8[3]) << 16; + + *comp = float(depth) / float(16777215.0f); + } + else if(fmt.compByteWidth == 2) + { + const uint16_t *u16 = (const uint16_t *)data; + const int16_t *i16 = (const int16_t *)data; + + if(compType == CompType::Float) + { + *comp = ConvertFromHalf(*u16); + } + else if(compType == CompType::UInt || compType == CompType::UScaled) + { + *comp = float(*u16); + } + else if(compType == CompType::SInt || compType == CompType::SScaled) + { + *comp = float(*i16); + } + // 16-bit depth is UNORM + else if(compType == CompType::UNorm || compType == CompType::Depth) + { + *comp = float(*u16) / 65535.0f; + } + else if(compType == CompType::SNorm) + { + float f = -1.0f; + + if(*i16 == -32768) + f = -1.0f; + else + f = ((float)*i16) / 32767.0f; + + *comp = f; + } + } + else if(fmt.compByteWidth == 1) + { + const uint8_t *u8 = (const uint8_t *)data; + const int8_t *i8 = (const int8_t *)data; + + if(compType == CompType::UInt || compType == CompType::UScaled) + { + *comp = float(*u8); + } + else if(compType == CompType::SInt || compType == CompType::SScaled) + { + *comp = float(*i8); + } + else if(compType == CompType::UNormSRGB) + { + *comp = SRGB8_lookuptable[*u8]; + } + else if(compType == CompType::UNorm) + { + *comp = float(*u8) / 255.0f; + } + else if(compType == CompType::SNorm) + { + float f = -1.0f; + + if(*i8 == -128) + f = -1.0f; + else + f = ((float)*i8) / 127.0f; + + *comp = f; + } + } else - f = ((float)*i16) / 32767.0f; + { + RDCERR("Unexpected format to convert from %u %u", fmt.compByteWidth, compType); + } - return f; + comp++; } - } - else if(fmt.compByteWidth == 1) - { - const uint8_t *u8 = (const uint8_t *)data; - const int8_t *i8 = (const int8_t *)data; - if(fmt.compType == CompType::UInt || fmt.compType == CompType::UScaled) - { - return float(*u8); - } - else if(fmt.compType == CompType::SInt || fmt.compType == CompType::SScaled) - { - return float(*i8); - } - else if(fmt.compType == CompType::UNormSRGB) - { - return SRGB8_lookuptable[*u8]; - } - else if(fmt.compType == CompType::UNorm) - { - return float(*u8) / 255.0f; - } - else if(fmt.compType == CompType::SNorm) - { - float f = -1.0f; - - if(*i8 == -128) - f = -1.0f; - else - f = ((float)*i8) / 127.0f; - - return f; - } + if(fmt.BGRAOrder()) + std::swap(ret.x, ret.z); } - RDCERR("Unexpected format to convert from %u %u", fmt.compByteWidth, fmt.compType); - - return 0.0f; + return ret; } #if ENABLED(ENABLE_UNIT_TESTS) diff --git a/renderdoc/maths/formatpacking.h b/renderdoc/maths/formatpacking.h index 591fdf060..76a548f6c 100644 --- a/renderdoc/maths/formatpacking.h +++ b/renderdoc/maths/formatpacking.h @@ -103,4 +103,4 @@ float ConvertLinearToSRGB(float linear); typedef uint8_t byte; struct ResourceFormat; -float ConvertComponent(const ResourceFormat &fmt, const byte *data); +FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data); diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 79df1ae3d..49279ac5b 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -1267,7 +1267,7 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path if(saveFmt.compType == CompType::Typeless) saveFmt.compType = saveFmt.compByteWidth == 4 ? CompType::Float : CompType::UNorm; - uint32_t pixStride = saveFmt.compCount * saveFmt.compByteWidth; + uint32_t pixStride = saveFmt.ElementSize(); // 24-bit depth still has a stride of 4 bytes. if(saveFmt.compType == CompType::Depth && pixStride == 3) @@ -1277,97 +1277,52 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path { for(uint32_t x = 0; x < td.width; x++) { - float r = 0.0f; - float g = 0.0f; - float b = 0.0f; - float a = 1.0f; - - if(saveFmt.type == ResourceFormatType::R10G10B10A2) - { - uint32_t *u32 = (uint32_t *)srcData; - - Vec4f vec = ConvertFromR10G10B10A2(*u32); - - r = vec.x; - g = vec.y; - b = vec.z; - a = vec.w; - - srcData += 4; - } - else if(saveFmt.type == ResourceFormatType::R11G11B10) - { - uint32_t *u32 = (uint32_t *)srcData; - - Vec3f vec = ConvertFromR11G11B10(*u32); - - r = vec.x; - g = vec.y; - b = vec.z; - a = 1.0f; - - srcData += 4; - } - else - { - if(saveFmt.compCount >= 1) - r = ConvertComponent(saveFmt, srcData + saveFmt.compByteWidth * 0); - if(saveFmt.compCount >= 2) - g = ConvertComponent(saveFmt, srcData + saveFmt.compByteWidth * 1); - if(saveFmt.compCount >= 3) - b = ConvertComponent(saveFmt, srcData + saveFmt.compByteWidth * 2); - if(saveFmt.compCount >= 4) - a = ConvertComponent(saveFmt, srcData + saveFmt.compByteWidth * 3); - - srcData += pixStride; - } - - if(saveFmt.BGRAOrder()) - std::swap(r, b); + FloatVector pixel = ConvertComponents(saveFmt, srcData); + srcData += pixStride; // HDR can't represent negative values if(sd.destType == FileType::HDR) { - r = RDCMAX(r, 0.0f); - g = RDCMAX(g, 0.0f); - b = RDCMAX(b, 0.0f); - a = RDCMAX(a, 0.0f); + pixel.x = RDCMAX(pixel.x, 0.0f); + pixel.y = RDCMAX(pixel.y, 0.0f); + pixel.z = RDCMAX(pixel.z, 0.0f); + pixel.w = RDCMAX(pixel.w, 0.0f); } if(sd.channelExtract == 0) { - g = b = r; - a = 1.0f; + pixel.y = pixel.z = pixel.x; + pixel.w = 1.0f; } - if(sd.channelExtract == 1) + else if(sd.channelExtract == 1) { - r = b = g; - a = 1.0f; + pixel.x = pixel.z = pixel.y; + pixel.w = 1.0f; } - if(sd.channelExtract == 2) + else if(sd.channelExtract == 2) { - r = g = b; - a = 1.0f; + pixel.x = pixel.y = pixel.z; + pixel.w = 1.0f; } - if(sd.channelExtract == 3) + else if(sd.channelExtract == 3) { - r = g = b = a; - a = 1.0f; + pixel.x = pixel.y = pixel.z = pixel.w; + pixel.w = 1.0f; } if(fldata) { - fldata[(y * td.width + x) * 4 + 0] = r; - fldata[(y * td.width + x) * 4 + 1] = g; - fldata[(y * td.width + x) * 4 + 2] = b; - fldata[(y * td.width + x) * 4 + 3] = a; + fldata[(y * td.width + x) * 4 + 0] = pixel.x; + fldata[(y * td.width + x) * 4 + 1] = pixel.y; + fldata[(y * td.width + x) * 4 + 2] = pixel.z; + fldata[(y * td.width + x) * 4 + 3] = pixel.w; } else { - abgr[0][(y * td.width + x)] = a; - abgr[1][(y * td.width + x)] = b; - abgr[2][(y * td.width + x)] = g; - abgr[3][(y * td.width + x)] = r; + abgr[0][(y * td.width + x)] = pixel.w; + abgr[1][(y * td.width + x)] = pixel.z; + abgr[2][(y * td.width + x)] = pixel.y; + abgr[3][(y * td.width + x)] = pixel.x; } } } diff --git a/renderdoc/replay/replay_driver.cpp b/renderdoc/replay/replay_driver.cpp index cbd48fe3a..b8a32a1ca 100644 --- a/renderdoc/replay/replay_driver.cpp +++ b/renderdoc/replay/replay_driver.cpp @@ -597,71 +597,15 @@ FloatVector HighlightCache::InterpretVertex(const byte *data, uint32_t vert, uint32_t vertexByteStride, const ResourceFormat &fmt, const byte *end, bool &valid) { - FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); - data += vert * vertexByteStride; - float *out = &ret.x; - - if(fmt.type == ResourceFormatType::R10G10B10A2) - { - if(data + 4 >= end) - { - valid = false; - return ret; - } - - Vec4f v; - if(fmt.compType == CompType::SNorm) - v = ConvertFromR10G10B10A2SNorm(*(const uint32_t *)data); - else - v = ConvertFromR10G10B10A2(*(const uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - ret.w = v.w; - return ret; - } - else if(fmt.type == ResourceFormatType::R11G11B10) - { - if(data + 4 >= end) - { - valid = false; - return ret; - } - - Vec3f v = ConvertFromR11G11B10(*(const uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - return ret; - } - - if(data + fmt.compCount * fmt.compByteWidth > end) + if(data + fmt.ElementSize() > end) { valid = false; - return ret; + return FloatVector(0.0f, 0.0f, 0.0f, 1.0f); } - for(uint32_t i = 0; i < fmt.compCount; i++) - { - *out = ConvertComponent(fmt, data); - - data += fmt.compByteWidth; - out++; - } - - if(fmt.BGRAOrder()) - { - FloatVector reversed; - reversed.x = ret.z; - reversed.y = ret.y; - reversed.z = ret.x; - reversed.w = ret.w; - return reversed; - } - - return ret; + return ConvertComponents(fmt, data); } uint64_t inthash(uint64_t val, uint64_t seed)