LibGL+LibGPU+LibSoftGPU: Move SamplerConfig to LibGPU

This commit is contained in:
Stephan Unverwerth 2022-03-27 14:55:31 +02:00 committed by Andreas Kling
parent 54307a9cd3
commit e7450fa940
Notes: sideshowbarker 2024-07-17 14:23:25 +09:00
6 changed files with 103 additions and 87 deletions

View File

@ -2909,7 +2909,7 @@ void GLContext::sync_device_sampler_config()
if (!texture_unit.texture_2d_enabled())
continue;
SoftGPU::SamplerConfig config;
GPU::SamplerConfig config;
auto texture_2d = texture_unit.texture_2d_target_texture();
if (texture_2d.is_null()) {
@ -2924,28 +2924,28 @@ void GLContext::sync_device_sampler_config()
switch (sampler.min_filter()) {
case GL_NEAREST:
config.texture_min_filter = SoftGPU::TextureFilter::Nearest;
config.mipmap_filter = SoftGPU::MipMapFilter::None;
config.texture_min_filter = GPU::TextureFilter::Nearest;
config.mipmap_filter = GPU::MipMapFilter::None;
break;
case GL_LINEAR:
config.texture_min_filter = SoftGPU::TextureFilter::Linear;
config.mipmap_filter = SoftGPU::MipMapFilter::None;
config.texture_min_filter = GPU::TextureFilter::Linear;
config.mipmap_filter = GPU::MipMapFilter::None;
break;
case GL_NEAREST_MIPMAP_NEAREST:
config.texture_min_filter = SoftGPU::TextureFilter::Nearest;
config.mipmap_filter = SoftGPU::MipMapFilter::Nearest;
config.texture_min_filter = GPU::TextureFilter::Nearest;
config.mipmap_filter = GPU::MipMapFilter::Nearest;
break;
case GL_LINEAR_MIPMAP_NEAREST:
config.texture_min_filter = SoftGPU::TextureFilter::Linear;
config.mipmap_filter = SoftGPU::MipMapFilter::Nearest;
config.texture_min_filter = GPU::TextureFilter::Linear;
config.mipmap_filter = GPU::MipMapFilter::Nearest;
break;
case GL_NEAREST_MIPMAP_LINEAR:
config.texture_min_filter = SoftGPU::TextureFilter::Nearest;
config.mipmap_filter = SoftGPU::MipMapFilter::Linear;
config.texture_min_filter = GPU::TextureFilter::Nearest;
config.mipmap_filter = GPU::MipMapFilter::Linear;
break;
case GL_LINEAR_MIPMAP_LINEAR:
config.texture_min_filter = SoftGPU::TextureFilter::Linear;
config.mipmap_filter = SoftGPU::MipMapFilter::Linear;
config.texture_min_filter = GPU::TextureFilter::Linear;
config.mipmap_filter = GPU::MipMapFilter::Linear;
break;
default:
VERIFY_NOT_REACHED();
@ -2953,10 +2953,10 @@ void GLContext::sync_device_sampler_config()
switch (sampler.mag_filter()) {
case GL_NEAREST:
config.texture_mag_filter = SoftGPU::TextureFilter::Nearest;
config.texture_mag_filter = GPU::TextureFilter::Nearest;
break;
case GL_LINEAR:
config.texture_mag_filter = SoftGPU::TextureFilter::Linear;
config.texture_mag_filter = GPU::TextureFilter::Linear;
break;
default:
VERIFY_NOT_REACHED();
@ -2964,19 +2964,19 @@ void GLContext::sync_device_sampler_config()
switch (sampler.wrap_s_mode()) {
case GL_CLAMP:
config.texture_wrap_u = SoftGPU::TextureWrapMode::Clamp;
config.texture_wrap_u = GPU::TextureWrapMode::Clamp;
break;
case GL_CLAMP_TO_BORDER:
config.texture_wrap_u = SoftGPU::TextureWrapMode::ClampToBorder;
config.texture_wrap_u = GPU::TextureWrapMode::ClampToBorder;
break;
case GL_CLAMP_TO_EDGE:
config.texture_wrap_u = SoftGPU::TextureWrapMode::ClampToEdge;
config.texture_wrap_u = GPU::TextureWrapMode::ClampToEdge;
break;
case GL_REPEAT:
config.texture_wrap_u = SoftGPU::TextureWrapMode::Repeat;
config.texture_wrap_u = GPU::TextureWrapMode::Repeat;
break;
case GL_MIRRORED_REPEAT:
config.texture_wrap_u = SoftGPU::TextureWrapMode::MirroredRepeat;
config.texture_wrap_u = GPU::TextureWrapMode::MirroredRepeat;
break;
default:
VERIFY_NOT_REACHED();
@ -2984,19 +2984,19 @@ void GLContext::sync_device_sampler_config()
switch (sampler.wrap_t_mode()) {
case GL_CLAMP:
config.texture_wrap_v = SoftGPU::TextureWrapMode::Clamp;
config.texture_wrap_v = GPU::TextureWrapMode::Clamp;
break;
case GL_CLAMP_TO_BORDER:
config.texture_wrap_v = SoftGPU::TextureWrapMode::ClampToBorder;
config.texture_wrap_v = GPU::TextureWrapMode::ClampToBorder;
break;
case GL_CLAMP_TO_EDGE:
config.texture_wrap_v = SoftGPU::TextureWrapMode::ClampToEdge;
config.texture_wrap_v = GPU::TextureWrapMode::ClampToEdge;
break;
case GL_REPEAT:
config.texture_wrap_v = SoftGPU::TextureWrapMode::Repeat;
config.texture_wrap_v = GPU::TextureWrapMode::Repeat;
break;
case GL_MIRRORED_REPEAT:
config.texture_wrap_v = SoftGPU::TextureWrapMode::MirroredRepeat;
config.texture_wrap_v = GPU::TextureWrapMode::MirroredRepeat;
break;
default:
VERIFY_NOT_REACHED();
@ -3004,13 +3004,13 @@ void GLContext::sync_device_sampler_config()
switch (texture_unit.env_mode()) {
case GL_MODULATE:
config.fixed_function_texture_env_mode = SoftGPU::TextureEnvMode::Modulate;
config.fixed_function_texture_env_mode = GPU::TextureEnvMode::Modulate;
break;
case GL_REPLACE:
config.fixed_function_texture_env_mode = SoftGPU::TextureEnvMode::Replace;
config.fixed_function_texture_env_mode = GPU::TextureEnvMode::Replace;
break;
case GL_DECAL:
config.fixed_function_texture_env_mode = SoftGPU::TextureEnvMode::Decal;
config.fixed_function_texture_env_mode = GPU::TextureEnvMode::Decal;
break;
default:
VERIFY_NOT_REACHED();

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGfx/Vector4.h>
#include <LibSoftGPU/Image.h>
namespace GPU {
enum class TextureFilter {
Nearest,
Linear,
};
enum class MipMapFilter {
None,
Nearest,
Linear,
};
enum class TextureWrapMode {
Repeat,
MirroredRepeat,
Clamp,
ClampToBorder,
ClampToEdge,
};
enum class TextureEnvMode {
Modulate,
Replace,
Decal,
};
struct SamplerConfig final {
RefPtr<SoftGPU::Image> bound_image;
MipMapFilter mipmap_filter { MipMapFilter::Nearest };
TextureFilter texture_mag_filter { TextureFilter::Linear };
TextureFilter texture_min_filter { TextureFilter::Linear };
TextureWrapMode texture_wrap_u { TextureWrapMode::Repeat };
TextureWrapMode texture_wrap_v { TextureWrapMode::Repeat };
TextureWrapMode texture_wrap_w { TextureWrapMode::Repeat };
FloatVector4 border_color { 0, 0, 0, 1 };
TextureEnvMode fixed_function_texture_env_mode { TextureEnvMode::Modulate };
};
}

View File

@ -977,13 +977,13 @@ ALWAYS_INLINE void Device::shade_fragments(PixelQuad& quad)
// FIXME: Implement more blend modes
switch (sampler.config().fixed_function_texture_env_mode) {
case SoftGPU::TextureEnvMode::Modulate:
case GPU::TextureEnvMode::Modulate:
quad.out_color = quad.out_color * texel;
break;
case SoftGPU::TextureEnvMode::Replace:
case GPU::TextureEnvMode::Replace:
quad.out_color = texel;
break;
case SoftGPU::TextureEnvMode::Decal: {
case GPU::TextureEnvMode::Decal: {
auto dst_alpha = texel.w();
quad.out_color.set_x(mix(quad.out_color.x(), texel.x(), dst_alpha));
quad.out_color.set_y(mix(quad.out_color.y(), texel.y(), dst_alpha));
@ -1231,7 +1231,7 @@ NonnullRefPtr<Image> Device::create_image(GPU::ImageFormat format, unsigned widt
return adopt_ref(*new Image(width, height, depth, levels, layers));
}
void Device::set_sampler_config(unsigned sampler, SamplerConfig const& config)
void Device::set_sampler_config(unsigned sampler, GPU::SamplerConfig const& config)
{
m_samplers[sampler].set_config(config);
}

View File

@ -14,6 +14,7 @@
#include <LibGPU/DeviceInfo.h>
#include <LibGPU/Enums.h>
#include <LibGPU/ImageFormat.h>
#include <LibGPU/SamplerConfig.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Matrix3x3.h>
#include <LibGfx/Matrix4x4.h>
@ -132,7 +133,7 @@ public:
NonnullRefPtr<Image> create_image(GPU::ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers);
void set_sampler_config(unsigned, SamplerConfig const&);
void set_sampler_config(unsigned, GPU::SamplerConfig const&);
void set_light_state(unsigned, Light const&);
void set_material_state(GPU::Face, Material const&);
void set_stencil_configuration(GPU::Face, StencilConfiguration const&);

View File

@ -52,20 +52,20 @@ static f32x4 wrap_mirrored_repeat(f32x4 value, u32x4 num_texels)
return wrap_clamp_to_edge(is_odd ? 1 - frac : frac, num_texels);
}
static f32x4 wrap(f32x4 value, TextureWrapMode mode, u32x4 num_texels)
static f32x4 wrap(f32x4 value, GPU::TextureWrapMode mode, u32x4 num_texels)
{
switch (mode) {
case TextureWrapMode::Repeat:
case GPU::TextureWrapMode::Repeat:
return wrap_repeat(value);
case TextureWrapMode::MirroredRepeat:
case GPU::TextureWrapMode::MirroredRepeat:
return wrap_mirrored_repeat(value, num_texels);
case TextureWrapMode::Clamp:
case GPU::TextureWrapMode::Clamp:
if constexpr (CLAMP_DEPRECATED_BEHAVIOR) {
return wrap_clamp(value);
}
return wrap_clamp_to_edge(value, num_texels);
case TextureWrapMode::ClampToBorder:
case TextureWrapMode::ClampToEdge:
case GPU::TextureWrapMode::ClampToBorder:
case GPU::TextureWrapMode::ClampToEdge:
return wrap_clamp_to_edge(value, num_texels);
default:
VERIFY_NOT_REACHED();
@ -132,7 +132,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv)
if (scale_factor[0] <= 1.f)
return sample_2d_lod(uv, expand4(base_level), m_config.texture_mag_filter);
if (m_config.mipmap_filter == MipMapFilter::None)
if (m_config.mipmap_filter == GPU::MipMapFilter::None)
return sample_2d_lod(uv, expand4(base_level), m_config.texture_min_filter);
// FIXME: Instead of clamping to num_levels - 1, actually make the max mipmap level configurable with glTexParameteri(GL_TEXTURE_MAX_LEVEL, max_level)
@ -142,7 +142,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv)
auto lower_level_texel = sample_2d_lod(uv, to_u32x4(level), m_config.texture_min_filter);
if (m_config.mipmap_filter == MipMapFilter::Nearest)
if (m_config.mipmap_filter == GPU::MipMapFilter::Nearest)
return lower_level_texel;
auto higher_level_texel = sample_2d_lod(uv, to_u32x4(min(level + 1.f, max_level)), m_config.texture_min_filter);
@ -150,7 +150,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv)
return mix(lower_level_texel, higher_level_texel, frac_int_range(level));
}
Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const& uv, AK::SIMD::u32x4 level, TextureFilter filter) const
Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const& uv, AK::SIMD::u32x4 level, GPU::TextureFilter filter) const
{
auto const& image = *m_config.bound_image;
u32x4 const layer = expand4(0u);
@ -177,7 +177,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const&
f32x4 u = s * to_f32x4(width);
f32x4 v = t * to_f32x4(height);
if (filter == TextureFilter::Nearest) {
if (filter == GPU::TextureFilter::Nearest) {
u32x4 i = to_u32x4(u);
u32x4 j = to_u32x4(v);
u32x4 k = expand4(0u);
@ -196,7 +196,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const&
u32x4 j0 = to_u32x4(floor_int_range(v));
u32x4 j1 = j0 + 1;
if (m_config.texture_wrap_u == TextureWrapMode::Repeat) {
if (m_config.texture_wrap_u == GPU::TextureWrapMode::Repeat) {
if (image.width_is_power_of_two()) {
i0 = i0 & width_mask;
i1 = i1 & width_mask;
@ -206,7 +206,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const&
}
}
if (m_config.texture_wrap_v == TextureWrapMode::Repeat) {
if (m_config.texture_wrap_v == GPU::TextureWrapMode::Repeat) {
if (image.height_is_power_of_two()) {
j0 = j0 & height_mask;
j1 = j1 & height_mask;
@ -220,7 +220,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const&
Vector4<f32x4> t0, t1, t2, t3;
if (m_config.texture_wrap_u == TextureWrapMode::Repeat && m_config.texture_wrap_v == TextureWrapMode::Repeat) {
if (m_config.texture_wrap_u == GPU::TextureWrapMode::Repeat && m_config.texture_wrap_v == GPU::TextureWrapMode::Repeat) {
t0 = texel4(image, layer, level, i0, j0, k);
t1 = texel4(image, layer, level, i1, j0, k);
t2 = texel4(image, layer, level, i0, j1, k);

View File

@ -8,60 +8,24 @@
#include <AK/RefPtr.h>
#include <AK/SIMD.h>
#include <LibGPU/SamplerConfig.h>
#include <LibGfx/Vector2.h>
#include <LibGfx/Vector4.h>
#include <LibSoftGPU/Image.h>
namespace SoftGPU {
enum class TextureFilter {
Nearest,
Linear,
};
enum class MipMapFilter {
None,
Nearest,
Linear,
};
enum class TextureWrapMode {
Repeat,
MirroredRepeat,
Clamp,
ClampToBorder,
ClampToEdge,
};
enum class TextureEnvMode {
Modulate,
Replace,
Decal,
};
struct SamplerConfig final {
RefPtr<Image> bound_image;
MipMapFilter mipmap_filter { MipMapFilter::Nearest };
TextureFilter texture_mag_filter { TextureFilter::Linear };
TextureFilter texture_min_filter { TextureFilter::Linear };
TextureWrapMode texture_wrap_u { TextureWrapMode::Repeat };
TextureWrapMode texture_wrap_v { TextureWrapMode::Repeat };
TextureWrapMode texture_wrap_w { TextureWrapMode::Repeat };
FloatVector4 border_color { 0, 0, 0, 1 };
TextureEnvMode fixed_function_texture_env_mode { TextureEnvMode::Modulate };
};
class Sampler final {
public:
Vector4<AK::SIMD::f32x4> sample_2d(Vector2<AK::SIMD::f32x4> const& uv) const;
void set_config(SamplerConfig const& config) { m_config = config; }
SamplerConfig const& config() const { return m_config; }
void set_config(GPU::SamplerConfig const& config) { m_config = config; }
GPU::SamplerConfig const& config() const { return m_config; }
private:
Vector4<AK::SIMD::f32x4> sample_2d_lod(Vector2<AK::SIMD::f32x4> const& uv, AK::SIMD::u32x4 level, TextureFilter) const;
Vector4<AK::SIMD::f32x4> sample_2d_lod(Vector2<AK::SIMD::f32x4> const& uv, AK::SIMD::u32x4 level, GPU::TextureFilter) const;
SamplerConfig m_config;
GPU::SamplerConfig m_config;
};
}