{"record":{"id":"6a30abfb5c99ba53","repo":"stride3d/stride","slug":"support-only-output-scaling-to-the-same-direction","errorCode":null,"errorMessage":"Support only output scaling to the same direction","messagePattern":"Support only output scaling to the same direction","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageMultiScaler.cs","lineNumber":145,"sourceCode":"                    outputPixelFormat = outputTexture.ViewFormat;\n\n                    var outputSize = outputTexture.Size;\n\n                    // Verify pixel format\n                    if (outputSize < minSize || outputSize > maxSize)\n                    {\n                        throw new InvalidOperationException(\"Unsupported texture size [{0}] out of limit [{1} - {2}]\".ToFormat(outputTexture.Size, minSize, maxSize));\n                    }\n\n                    if (inputSize == outputSize)\n                    {\n                        throw new InvalidOperationException(\"Input and output texture cannot have same size [{0}]\".ToFormat(inputSize));\n                    }\n\n                    int newScalingDirection = outputSize.CompareTo(inputSize);\n                    if (scalingDirection != 0 && Math.Sign(scalingDirection) != Math.Sign(newScalingDirection))\n                    {\n                        throw new InvalidOperationException(\"Support only output scaling to the same direction\");\n                    }\n                    scalingDirection = newScalingDirection;\n\n                    // Check that we are scaling to different texture sizes\n                    foreach (var existingOutput in outputTextures)\n                    {\n                        if (existingOutput.Size == outputTexture.Size)\n                        {\n                            throw new InvalidOperationException(\"A texture with size [{0}] already exist with the same output size\".ToFormat(existingOutput.Size));\n                        }\n                    }\n\n                    // If the textrue is valid use it\n                    outputTextures.Add(outputTexture);\n                }\n            }\n\n            return outputTextures.Count > 0;","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageMultiScaler.cs#L127-L163","documentation":"ImageMultiScaler tracks the scaling direction (up vs down) established by its first output. Once set, all outputs must scale the same way; PrepareScaling throws InvalidOperationException if a later output's size relative to the input reverses that direction (e.g. first output is half-size downscale, second is double-size upscale).","triggerScenarios":"Mixing larger-than-input and smaller-than-input output textures on a single ImageMultiScaler instance, then rendering a frame that triggers PrepareScaling via DrawCore.","commonSituations":"Using one multi-scaler for both a blurred downsample chain and an upscaled bloom target; refactored code reusing one scaler where two directionally distinct scalers are needed.","solutions":["Use one ImageMultiScaler per scaling direction: one for all downscaled outputs, another for all upscaled outputs.","Ensure every output added to the same scaler is consistently smaller than the input, or consistently larger.","Compute output sizes from a single ratio direction (all factors < 1 or all > 1) in setup code."],"exampleFix":"// before\nscaler.SetOutput(0, rtHalf);   // downscale\nscaler.SetOutput(1, rtDouble); // upscale -> throws\n// after\ndownScaler.SetOutput(0, rtHalf);\nupScaler.SetOutput(0, rtDouble);","handlingStrategy":"validation","validationCode":"bool allDown = outputs.All(o => o.Size < inputSize);\nbool allUp = outputs.All(o => o.Size > inputSize);\nif (!allDown && !allUp) throw new InvalidOperationException(\"Mixing upscale and downscale outputs on one ImageMultiScaler is unsupported\");","typeGuard":null,"tryCatchPattern":"try { scaler.Draw(context); }\ncatch (InvalidOperationException) { Log.Warning(\"Mixed scaling directions; splitting scalers at next init\"); }","preventionTips":["Keep one ImageMultiScaler per scaling direction (downscales on one, upscales on another).","Derive all output sizes from ratios consistently < 1 or > 1.","Document the direction constraint next to the scaler setup code."],"tags":["scaling-direction","unsupported-operation","rendering","stride"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}