| 157 | } |
| 158 | |
| 159 | void FrameCapture::captureOutput(RenderContext* pRenderContext, RenderGraph* pGraph, const uint32_t outputIndex) |
| 160 | { |
| 161 | const std::string outputName = pGraph->getOutputName(outputIndex); |
| 162 | const std::string basename = getOutputNamePrefix(outputName) + std::to_string(mpRenderer->getGlobalClock().getFrame()); |
| 163 | |
| 164 | const ref<Texture> pOutput = pGraph->getOutput(outputIndex)->asTexture(); |
| 165 | if (!pOutput) FALCOR_THROW("Graph output {} is not a texture", outputName); |
| 166 | |
| 167 | const ResourceFormat format = pOutput->getFormat(); |
| 168 | const uint32_t channels = getFormatChannelCount(format); |
| 169 | |
| 170 | for (auto mask : pGraph->getOutputMasks(outputIndex)) |
| 171 | { |
| 172 | // Determine output color channels and filename suffix. |
| 173 | std::string suffix; |
| 174 | uint32_t outputChannels = 0; |
| 175 | |
| 176 | switch (mask) |
| 177 | { |
| 178 | case TextureChannelFlags::Red: suffix = ".R"; outputChannels = 1; break; |
| 179 | case TextureChannelFlags::Green: suffix = ".G"; outputChannels = 1; break; |
| 180 | case TextureChannelFlags::Blue: suffix = ".B"; outputChannels = 1; break; |
| 181 | case TextureChannelFlags::Alpha: suffix = ".A"; outputChannels = 1; break; |
| 182 | case TextureChannelFlags::RGB: /* No suffix */ outputChannels = 3; break; |
| 183 | case TextureChannelFlags::RGBA: suffix = ".RGBA"; outputChannels = 4; break; |
| 184 | default: |
| 185 | logWarning("Graph output {} mask {:#x} is not supported. Skipping.", outputName, (uint32_t)mask); |
| 186 | continue; |
| 187 | } |
| 188 | |
| 189 | // Copy relevant channels into new texture if necessary. |
| 190 | ref<Texture> pTex = pOutput; |
| 191 | if (outputChannels == 1 && channels > 1) |
| 192 | { |
| 193 | // Determine output format. |
| 194 | ResourceFormat outputFormat = ResourceFormat::Unknown; |
| 195 | uint bits = getNumChannelBits(format, mask); |
| 196 | |
| 197 | switch (getFormatType(format)) |
| 198 | { |
| 199 | case FormatType::Unorm: |
| 200 | case FormatType::UnormSrgb: |
| 201 | if (bits == 8) outputFormat = ResourceFormat::R8Unorm; |
| 202 | else if (bits == 16) outputFormat = ResourceFormat::R16Unorm; |
| 203 | break; |
| 204 | case FormatType::Snorm: |
| 205 | if (bits == 8) outputFormat = ResourceFormat::R8Snorm; |
| 206 | else if (bits == 16) outputFormat = ResourceFormat::R16Snorm; |
| 207 | break; |
| 208 | case FormatType::Uint: |
| 209 | if (bits == 8) outputFormat = ResourceFormat::R8Uint; |
| 210 | else if (bits == 16) outputFormat = ResourceFormat::R16Uint; |
| 211 | else if (bits == 32) outputFormat = ResourceFormat::R32Uint; |
| 212 | break; |
| 213 | case FormatType::Sint: |
| 214 | if (bits == 8) outputFormat = ResourceFormat::R8Int; |
| 215 | else if (bits == 16) outputFormat = ResourceFormat::R16Int; |
| 216 | else if (bits == 32) outputFormat = ResourceFormat::R32Int; |
nothing calls this directly
no test coverage detected