flutter3d_cpu 0.6.0
flutter3d_cpu: ^0.6.0 copied to clipboard
A software backend for flutter3d_hardware: no GPU, no shading language, and therefore the sharpest test of whether the interface is an interface.
0.6.0 #
- Two reference pictures, and no code.
cube-shadow-crowdedandcube-shadow-manyare recorded again in this backend's own set. The scenes did not change; the demo that draws them stopped handing out point-shadow atlas rows on frames drawn before its model landed, and the software set held the same latched rows the other three did. The cross-backend gate is what caught it — 5037 and 1346 differing pixels against a budget of 0.02% — and all four sets now agree on the rows the ranking chose. - The rasteriser, the encoder and every capability answer are byte for byte 0.5.2's. A caller upgrading gets the same pixels out of the same calls; what moved is this package's test data.
0.5.2 #
- A vertex stage can be told which vertex it is drawing.
CpuVertexShaderByIndexaddsrunAt(vertexIndex, ...)besideCpuVertexShader.run, which is handed attributes and no index. A second interface rather than a member on the published one, so every stage that exists still compiles: the encoder callsrunAtwhen a stage implements it andrunotherwise. Morph targets are what needed it — a vertex has to look its own deltas up in a texture. lib/morph.glsl, transcribed. Deltas read out of a texture by vertex index and added to the position, normal and tangent, against the GLSL rather than againstMorphBlend: the same arithmetic on the host is a second source, and a transcription of a transcription drifts. Four tests hold it to a picture — weighting a target moves it, it lands whereMorphBlendputs it, half a weight lands between, and a weight of nought costs nothing.runAttakes the instance index as well as the vertex index, andlib/morph_instanced.glslis transcribed beside the one it extends: a batch whose copies wear different expressions draws them here too. The interface gained a parameter rather than a sibling because it had not been published yet — after this, adding one would break every implementer.- A float texture could not be uploaded at all, and said nothing.
createTextureFromPixelsmeasured every format at four bytes a texel, so anr32g32b32a32Float— sixteen — was refused as the wrong size and the caller saw a null. Texel size now comes from the format, and the float formats are decoded as floats rather than as eight-bit unorm.
0.5.1 #
- This backend was the one that was right, and its budget said otherwise.
Its transcription of the occlusion pass disagreed with Impeller over 7.647%
of the corner scene, written down as a defect budget for whoever fixed it.
What was wrong was the surface buffer's depth format on the two GPU backends;
this rasteriser keeps every channel as a
doublewhatever the format says, so it had the precision to draw the effect correctly and was being held to a picture that was not. The budget is 0.159% now, and reflections 0.633% to 0.025%. Seeflutter3d_shaders0.5.1. surface_depth_test.dart, holding the contract that channel now carries: a point round-tripped through it under a perspective camera and an orthographic one, and the two half-float numbers the change rests on.
0.5.0 #
CpuShaderLibrary.stagesis unmodifiable. It is built once and read afterwards, and a writer now breaks loudly rather than silently.- Follows the engine's widened callbacks and the physics package's contact filter.
0.4.2 #
maxAnisotropyis one, and means it. This rasteriser picks one level per triangle and takes one tap, so a sampler asking for eight is honoured on the hardware backends and ignored here — and the device says so rather than promising taps it does not take.anisotropic-flooris recorded in this backend's own set without them, and the cross-backend budget for the scene is the measured size of that difference, which is the one place the two sets are allowed to disagree on purpose.- A bundle loaded from bytes answers with the Dart this backend has.
CpuDevice.loadShaderscompiles nothing — there is nothing here to compile — soCpuLoadedShaderLibraryanswers each name the bundle claims with the device's own stage under that name, and refuses a bundle naming a stage it has no Dart for, naming the stages. An application's own look reaches this backend the way it always has, as a Dart stage handed toCpuDevice.shaders; the bundle that names it on the hardware backends then loads here too.CpuShaderLibrarycaches its handles so their identity survives a refresh. - A refresh that drops a stage in use is refused, naming it.
CpuLoadedShaderLibraryremembers every name it answered with a handle, and a bundle that no longer names one of them is refused before it is taken — the contractLoadedShaderLibrary.refreshnow states, kept the same way on every backend. Only a name that was handed out counts: a stage the bundle claimed and nobody asked for may come and go. readback, at once. Nothing here is in flight — the pass that wrote the floats ran to the end beforesubmitreturned — so the region is converted on the spot and the future is complete when it is handed back, which is the honest answer and what lets the engine's own tests of the callers run in a plainflutter test: a dark room climbing to the ceiling, two boxes picked apart.LuminanceandObjectIdtranscribed from the GLSL;auto-exposurejoins the golden set at 0.581% from Impeller.- Alpha masking, transcribed.
ReadSurface's discard under the cutoff had been left out on the grounds that no fixture exercised it; the picking stage needed the same hole, and an id pass that discards where the scene pass does not would pick what the eye cannot see.readSurfacenow answers null for a masked fragment under its cutoff and every lit model hands the null on,ObjectIdsamples the texture againstIdInfo.maskthe way the GLSL does, and the test is a red fence with a hole in front of a white box: the pick through the hole says box, and so does the pixel. - A stencil buffer, a byte per pixel beside the depth. Every one of the
eight operations, both masks, the reference and a state per face, tested
before the depth test and applied after the fragment stage — so a discard
writes nothing, as it does on hardware — with a fixture per rule in
stencil_test.dart. Nothing is asked per fragment while the test is off, so the thirty-four scenes that never mention it draw as they did. - The blend equation, factor by factor. Two states were recognised by
testing two of their factors, and
BlendState.keepDestination— zero and one — read as one and one. Every factor is a line now; the four that need a blend constant throw, because the interface has no way to set one. XrayShader, the transcription ofxray.frag: the albedo and not one word about the surface, soFragmentContext.surfaceis left null and the encoder writes nothing to attachment one.stencil-xrayjoins the golden set.- A pass renders into a cube face and a mip level.
CpuTexture.subresourcewalks to the array a face and a level own — the same structureBoundTexture.sampleCubereads — and every write of a pass goes through it;createCubeRenderTargetbuilds that structure empty, a chain per face.ProbePrefilterShadertranscribesprobe_prefilter.frag;probe-carjoins the golden set. - The blend constant, which this backend used to throw for.
setBlendColoris a field on the pass and four arms in the blend equation, so all fifteenBlendFactorvalues are drawn rather than eleven.supportsBlendColoranswers true.
0.4.1 #
- The lightmapped vertex stage and the lightmap term in the four lit models, transcribed from the GLSL; the mesh varyings grow by the coordinate.
- A compressed format is refused by name, and asked about first.
createTextureFromPixelsused to read block bytes as RGBA8 and hand back a texture full of noise; it throws naming the format now, andsupportsTextureFormatsays no to every block-compressed value before a loader gets that far, because this backend samples raw texels and always will.
0.4.0 #
CpuFramedisposes its images. It had nodisposeat all — one leakedui.Imageper presented frame — and two in-flight decodes could finish out of order. The previous image is disposed when a new one lands, the fresh one when the widget is already gone, and a sequence number keeps a stale frame from overwriting a newer one.
0.3.0 #
- The composite pass mirrors the grading, vignette, grain and dispersion the hardware backends apply, so the two reference sets stay comparable.
- Cube texture uploads validate each mip level's size rather than accepting anything that fits.
0.2.0 #
flutter3d_hardwarerasterised in Dart with no GPU under it: what the golden images are drawn with, and what a test renders a whole frame through.- Deliberately shares nothing with either hardware backend — no driver, no shading language, no command buffer — which is what makes agreeing with them mean something.