summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSoftGPU
AgeCommit message (Collapse)Author
2022-01-13LibGL+LibSoftGPU: Implement `glColorMaterial` and `GL_COLOR_MATERIAL`Jelle Raaijmakers
When `GL_COLOR_MATERIAL` is enabled, specific material parameters can be overwritten by the current color per-vertex during the lighting calculations. Which parameter is controlled by `glColorMaterial`. Also move the lighting calculations _before_ clipping, because the spec says so. As a result, we interpolate the resulting vertex color instead of the input color.
2022-01-13LibGL+LibSoftGPU: Calculate spotlight cutoff angle as degreesJelle Raaijmakers
We were storing the radians but never using that value in the GPU. We now directly use the degrees value.
2022-01-13LibSoftGPU: Change `Material` vectors to `FloatVector4`Jelle Raaijmakers
Same type, but more consistent with the rest of LibSoftGPU and LibGL.
2022-01-12LibSoftGPU: Don't render triangle strip if there's less than 3 verticesLuke Wilde
If there's less than 3 vertices, we cannot do triangle strip otherwise we will go out-of-bounds of the vertices vector. Required for Half-Life, which sometimes submits 0 vertices for triangle strip when drawing the electric disks around the pillars in Xen.
2022-01-12LibSoftGPU: Implement per-vertex Lighting during T&L StageJesse Buhagiar
We now perform per vertex lighting during the Transform and Lighting stage of the pipeline before the triangles are sent off to be rasterized.
2022-01-12LibSoftGPU: Transform normals during T&L stageJesse Buhagiar
As well as Vertex Positions, the normals also need to be transformed into eye-space so that lighting can be applied correctly.
2022-01-12LibGL+LibSoftGPU: Pass along lighting flag to Software GPUJesse Buhagiar
This was currently only set in the OpenGL context, as the previous architecture did all of the transformation in LibGL before passing the transformed triangles onto the rasterizer. As this has now changed, and we require the vertex data to be in eye-space before we can apply lighting, we need to pass this flag along as well via the GPU options.
2022-01-12LibGL+LibSoftGPU: Move lighting model parameters to SoftGPUJesse Buhagiar
Most of the T&L stuff is, like on an actual GPU, now done inside of LibSoftGPU. As such, it no longer makes sense to have specific values like the scene ambient color inside of LibGL as part of the GL context. These have now been moved into LibSoftGPU and use the same pattern as the render options to set/get.
2022-01-12LibGL: Flesh out `glMaterialf{v}`Jesse Buhagiar
These two functions have been turned from stubs into actually doing something. They now set the correspondingmaterial data member based on the value passed into the `pname`argument. Co-authored-by: Stephan Unverwerth <s.unverwerth@serenityos.org>
2022-01-12LibGL: Implement `glLightf{v}` and fix `gl.h` prototypeJesse Buhagiar
This implements the `glLightf{v}` family of functions used to set lighting parameters per light in the GL. It also fixes an incorrect prototype for the user exposed version of `glLightf{v}` in which `params` was not marked as `const`.
2022-01-12LibGL+LibSoftGPU: Add `GL_MAX_LIGHTS` to get_context_parameterJesse Buhagiar
This is required to allow lighting to work properly in the GL. We currently have the maximum number of lights in the software GL context set to 8, as this is the minimum that OpenGL mandates according to the spec.
2022-01-11LibSoftGPU: Only render complete primitivesJelle Raaijmakers
Previously, we were expecting triangles and quads to consist of complete sets of vertices. However, a more common behavior is to ignore all vertices that do not make up a full primitive. For example, OpenGL specifies for `GL_QUADS`: "The total number of vertices between Begin and End is 4n + k, where 0 ≤ k ≤ 3; if k is not zero, the final k vertices are ignored." This changes the behavior of `Device::draw_primitives()` to both return early if no full set of vertices was provided, and to ignore any additional vertices that are not part of a full set.
2022-01-09LibGL+LibSoftGPU: Implement viewport supportJelle Raaijmakers
This implements the `glViewport` API call, the coordinate transformation and the `GL_VIEWPORT` context parameter.
2022-01-09LibSoftGPU: Rename window coordinate transformation functionJelle Raaijmakers
The name `scissor_box_to_window_coordinates` was wildy inaccurate since we are actually transforming window coordinates into whatever the coordinate space of the backing bitmap is.
2022-01-09LibSoftGPU: Take sample from pixel centerStephan Unverwerth
This adds a half pixel offset to the edge value calculation in order to sample the triangle at pixel centers. This is in line with actual OpenGL rasterization rules and generates correctly interpolated vertex attributes including texture coordinates.
2022-01-09LibSoftGPU: Make divide-by-zero guard more explicit in stats overlayStephan Unverwerth
This previously assigned 1 to any divisor that was 0 which was a bit confusing
2022-01-09LibSoftGPU: Allow arbitrary render target sizesStephan Unverwerth
With the RASTERIZER_BLOCK_SIZE gone we can now render to any size, even odd ones. We have to be careful to not generate out of bounds accesses when calculating the render target and depth buffer pointers. Thus we check the coverage mask and generate nullptrs for pixels that will not be updated. This also masks out pixels that would touch the triangle but are outside the render target/scissor rect bounds.
2022-01-09LibSoftGPU: Also interpolate normal during triangle clippingStephan Unverwerth
2022-01-09LibSoftGPU: Move alpha test into separate functionStephan Unverwerth
2022-01-09LibSoftGPU: Move alpha blend factor setup out of triangle rasterizationStephan Unverwerth
Since the alpha blend configuration should not change between most calls of draw_primitives it makes no sense to reinitialize the blend factors for every rasterized triangle. The alpha blend factors are now set up whenever the device config changes. The blend factors are stored in struct AlphaBlendFactors.
2022-01-09LibSoftGPU: Make rasterization and shading member functions of DeviceStephan Unverwerth
This adds member functions Device::rasterize_triangle() and Device::shade_fragments(). They were free standing functions/lambdas previously which led to a lot of parameters being passed around.
2022-01-09LibSoftGPU: Vectorize color conversion from/to framebufferStephan Unverwerth
Functions to_rgba32 and to_vec4 now process 4 color values at the same time. Co-authored-by: Jesse Buhagiar <jooster669@gmail.com>
2022-01-09LibSoftGPU: Only interpolate fog values if fog is enabledStephan Unverwerth
2022-01-09LibSoftGPU: Add SIMD utilization counter to debug overlayStephan Unverwerth
This adds a counter to the debug overlay that displays the average percentage of SIMD lane utilization. This number represents the number of pixels that were output for each quad. A utilization of 100% means that all 4 SIMD lanes were used and no pixels were masked out before being written to the color buffer.
2022-01-09LibSoftGPU: Vectorize the rest of the rasterizer pipelineStephan Unverwerth
2022-01-09LibSoftGPU: Use bitwise and instead of modulus operator for POT texturesStephan Unverwerth
Where possible the sampler will wrap texture coordinates using a bitwise and instead of a modulus. This speeds up the calculation quite a bit.
2022-01-09LibSoftGPU: Vectorize texture sampling and shadingStephan Unverwerth
2022-01-09LibSoftGPU: Add PixelQuad struct that holds data for each rendered quadStephan Unverwerth
2022-01-09LibSoftGPU: Add SIMD.h with SoftGPU specific SIMD functionsStephan Unverwerth
Adds functions to expand Vector{2,3,4} to their SIMD equivalent.
2022-01-07Everywhere: Fix spelling mistakesmjz19910
2022-01-06LibSoftGPU: Implement 5 bits of subpixel precisionStephan Unverwerth
This snaps vertices to 1/32 of a pixel before rasterization resulting in smoother movement and less floaty appearance of moving triangles. This also reduces the severity of the artifacts in the glquake port. 5 bits should allow up to 1024x1024 render targets. Anything larger needs a different implementation.
2022-01-04LibSoftGPU: Shift U/V coordinates just once in `Sampler`Jelle Raaijmakers
2022-01-04LibSoftGPU: Use `AK::mix` instead of manual interpolationJelle Raaijmakers
2022-01-01LibSoftGPU: Add option to render a debug overlayStephan Unverwerth
This displays statistics regarding frame timings and number of pixels rendered. Timings are based on the time between draw_debug_overlay() invocations. This measures actual number of frames presented to the user vs. wall clock time so this also includes everything the app might do besides rendering. Triangles are counted after clipping. This number might actually be higher than the number of triangles coming from LibGL. Pixels are counted after the initial scissor and coverage test. Pixels rejected here are not counted. Shaded pixels is the percentage of all pixels that made it to the shading stage. Blended pixels is the percentage of shaded pixels that were alpha blended to the color buffer. Overdraw measures how many pixels were shaded vs. how many pixels the render target has. e.g. a 640x480 render target has 307200 pixels. If exactly that many pixels are shaded the overdraw number will read 0%. 614400 shaded pixels will read as an overdraw of 100%. Sampler calls is simply the number of times sampler.sample_2d() was called.
2022-01-01LibSoftGPU: Put all constexpr config options into Config.hStephan Unverwerth
2021-12-30LibGL+LibSoftGPU: Implement texture coordinate generationJelle Raaijmakers
Texture coordinate generation is the concept of automatically generating vertex texture coordinates instead of using the provided coordinates (i.e. `glTexCoord`). This commit implements support for: * The `GL_TEXTURE_GEN_Q/R/S/T` capabilities * The `GL_OBJECT_LINEAR`, `GL_EYE_LINEAR`, `GL_SPHERE_MAP`, `GL_REFLECTION_MAP` and `GL_NORMAL_MAP` modes * Object and eye plane coefficients (write-only at the moment) This changeset allows Tux Racer to render its terrain :^)
2021-12-30LibSoftGPU: Use eye coordinates for fog calculationJelle Raaijmakers
Now that we calculate and store eye coordinates for each vertex, we should use their `z` values for the fragment depth used in further fog calculations. This fixes the fog in Tux Racer :^)
2021-12-30LibGL+LibSoftGPU: Implement eye, clip, NDC and window coordinatesJelle Raaijmakers
This follows the OpenGL 1.5 spec much more closely. We need to store the eye coordinates especially, since they are used in texture coordinate generation and fog fragment depth calculation.
2021-12-30LibSoftGPU: Set obvious FP values for `depth_min/max`Jelle Raaijmakers
2021-12-30LibSoftGPU: Drop unnecessary FP divisions in `to_vec4`Jelle Raaijmakers
2021-12-30LibSoftGPU: Be less lenient towards unknown enum valuesJelle Raaijmakers
2021-12-30LibSoftGPU: Prevent fog from overwriting the alpha channelJelle Raaijmakers
Fog only affects the RGB channels according to the spec.
2021-12-30LibGL+LibSoftGPU: Implement normalization of normalsJelle Raaijmakers
* LibGL now supports the `GL_NORMALIZE` capability * LibSoftGPU transforms and normalizes the vertices' normals Normals are heavily used in texture coordinate generation, to be implemented in a future commit.
2021-12-30LibGL: Optimize float divisions in `unpack_color`Jelle Raaijmakers
For Tux Racer on my machine, this function would account for 15% of samples. After this change, that drops down to 9%.
2021-12-30LibGL: Defer depth writing until after alpha testingJelle Raaijmakers
In the OpenGL fixed function pipeline, alpha testing should happen before depth testing and writing. Since the tests are basically boolean ANDs, we can reorder them however we like to improve performance and as such, we perform early depth testing and delay the more expensive alpha testing until we know which pixels to test. However, we were already writing to the depth buffer during the depth test, even if the alpha test fails later on. Depth writing should only happen if depth testing _and_ writing is enabled. This change introduces depth staging, deferring the depth write until we are absolutely sure we should do so.
2021-12-27LibSoftGPU: Mark `wrap_clamp` as [[maybe_unused]]Jesse Buhagiar
This was breaking the fuzzer build becaues the function is not used if the `CLAMP_DEPRECATED_BEHAVIOR` constexpr is not `true` during compile time.
2021-12-27LibSoftGPU: Clamp to edge instead of borderJelle Raaijmakers
According to the Khronos FAQ on texture edge sampling, the `GL_CLAMP` option was never implemented in hardware and as such, it was deprecated. A lot of applications and games depend on `GL_CLAMP` not really meaning `GL_CLAMP` but `GL_CLAMP_TO_EDGE`, so we introduce an option to toggle this behavior at compile-time.
2021-12-27LibGL: Fix `GL_TRIANGLE_STRIP` rendering only half its trianglesJelle Raaijmakers
According to the documentation, we should switch around vertices every other triangle to prevent front-face culling from removing them. This allows Tux in Tux Racer to render correctly.
2021-12-24LibSoftGPU: Add method to copy texels between imagesStephan Unverwerth
Adds a method `copy_texels()` to class `Image` that copies a rect of texels from source image to destination.
2021-12-24LibGL+LibSoftGPU: Add method to query device infoStephan Unverwerth
This adds a method `info()` to SoftGPU that returns the name of the hardware vendor and device name, as well as the number of texture untis. LibGL uses the returned texture unit count to initialize its internal texture unit array.