mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 21:37:58 +03:00
LibGL+LibGPU+LibSoftGPU: Remove concept of layer
in favor of depth
Looking at how Khronos defines layers: https://www.khronos.org/opengl/wiki/Array_Texture We both have 3D textures and layers of 2D textures, which can both be encoded in our existing `Typed3DBuffer` as depth. Since we support depth already in the GPU API, remove layer everywhere. Also pass in `Texture2D::LOG2_MAX_TEXTURE_SIZE` as the maximum number of mipmap levels, so we do not allocate 999 levels on each Image instantiation.
This commit is contained in:
parent
44953a4301
commit
dda5987684
Notes:
sideshowbarker
2024-07-17 07:15:38 +09:00
Author: https://github.com/gmta Commit: https://github.com/SerenityOS/serenity/commit/dda5987684 Pull-request: https://github.com/SerenityOS/serenity/pull/15150 Reviewed-by: https://github.com/linusg ✅ Reviewed-by: https://github.com/sunverwerth ✅
@ -14,7 +14,7 @@ namespace GL {
|
||||
void Texture2D::download_texture_data(GLuint lod, GPU::ImageDataLayout output_layout, GLvoid* pixels)
|
||||
{
|
||||
VERIFY(!device_image().is_null());
|
||||
device_image()->read_texels(0, lod, { 0, 0, 0 }, pixels, output_layout);
|
||||
device_image()->read_texels(lod, { 0, 0, 0 }, pixels, output_layout);
|
||||
}
|
||||
|
||||
void Texture2D::upload_texture_data(GLuint lod, GLenum internal_format, GPU::ImageDataLayout input_layout, GLvoid const* pixels)
|
||||
|
@ -97,7 +97,7 @@ void GLContext::gl_copy_tex_image_2d(GLenum target, GLint level, GLenum internal
|
||||
|
||||
auto internal_pixel_format = pixel_format_for_internal_format(internalformat);
|
||||
if (level == 0) {
|
||||
texture_2d->set_device_image(m_rasterizer->create_image(internal_pixel_format, width, height, 1, 999, 1));
|
||||
texture_2d->set_device_image(m_rasterizer->create_image(internal_pixel_format, width, height, 1, Texture2D::LOG2_MAX_TEXTURE_SIZE));
|
||||
m_sampler_config_is_dirty = true;
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ void GLContext::gl_tex_image_2d(GLenum target, GLint level, GLint internal_forma
|
||||
// To be spec compliant we should create the device image once the texture has become complete and is used for rendering the first time.
|
||||
// All images that were attached before the device image was created need to be stored somewhere to be used to initialize the device image once complete.
|
||||
auto internal_pixel_format = pixel_format_for_internal_format(internal_format);
|
||||
texture_2d->set_device_image(m_rasterizer->create_image(internal_pixel_format, width, height, 1, 999, 1));
|
||||
texture_2d->set_device_image(m_rasterizer->create_image(internal_pixel_format, width, height, 1, Texture2D::LOG2_MAX_TEXTURE_SIZE));
|
||||
m_sampler_config_is_dirty = true;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
virtual RasterizerOptions options() const = 0;
|
||||
virtual LightModelParameters light_model() const = 0;
|
||||
|
||||
virtual NonnullRefPtr<Image> create_image(PixelFormat const&, u32 width, u32 height, u32 depth, u32 levels, u32 layers) = 0;
|
||||
virtual NonnullRefPtr<Image> create_image(PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels) = 0;
|
||||
|
||||
virtual void set_sampler_config(unsigned, SamplerConfig const&) = 0;
|
||||
virtual void set_light_state(unsigned, Light const&) = 0;
|
||||
|
@ -21,9 +21,9 @@ public:
|
||||
|
||||
virtual ~Image() { }
|
||||
|
||||
virtual void write_texels(u32 layer, u32 level, Vector3<i32> const& output_offset, void const* input_data, ImageDataLayout const&) = 0;
|
||||
virtual void read_texels(u32 layer, u32 level, Vector3<i32> const& input_offset, void* output_data, ImageDataLayout const&) const = 0;
|
||||
virtual void copy_texels(Image const& source, u32 source_layer, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_layer, u32 destination_level, Vector3<u32> const& destination_offset) = 0;
|
||||
virtual void write_texels(u32 level, Vector3<i32> const& output_offset, void const* input_data, ImageDataLayout const&) = 0;
|
||||
virtual void read_texels(u32 level, Vector3<i32> const& input_offset, void* output_data, ImageDataLayout const&) const = 0;
|
||||
virtual void copy_texels(Image const& source, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_level, Vector3<u32> const& destination_offset) = 0;
|
||||
|
||||
void const* ownership_token() const { return m_ownership_token; }
|
||||
bool has_same_ownership_token(Image const& other) const { return other.ownership_token() == ownership_token(); }
|
||||
|
@ -1473,7 +1473,7 @@ void Device::blit_from_color_buffer(NonnullRefPtr<GPU::Image> image, u32 level,
|
||||
|
||||
auto const& softgpu_image = reinterpret_cast<Image*>(image.ptr());
|
||||
auto output_layout = softgpu_image->image_data_layout(level, output_offset);
|
||||
auto* output_data = softgpu_image->texel_pointer(0, level, 0, 0, 0);
|
||||
auto* output_data = softgpu_image->texel_pointer(level, 0, 0, 0);
|
||||
|
||||
PixelConverter converter { input_layout, output_layout };
|
||||
auto conversion_result = converter.convert(input_data, output_data, {});
|
||||
@ -1512,7 +1512,7 @@ void Device::blit_from_depth_buffer(NonnullRefPtr<GPU::Image> image, u32 level,
|
||||
|
||||
auto const& softgpu_image = reinterpret_cast<Image*>(image.ptr());
|
||||
auto output_layout = softgpu_image->image_data_layout(level, output_offset);
|
||||
auto* output_data = softgpu_image->texel_pointer(0, level, 0, 0, 0);
|
||||
auto* output_data = softgpu_image->texel_pointer(level, 0, 0, 0);
|
||||
|
||||
PixelConverter converter { input_layout, output_layout };
|
||||
auto conversion_result = converter.convert(input_data, output_data, {});
|
||||
@ -1629,15 +1629,14 @@ void Device::set_light_model_params(GPU::LightModelParameters const& lighting_mo
|
||||
m_lighting_model = lighting_model;
|
||||
}
|
||||
|
||||
NonnullRefPtr<GPU::Image> Device::create_image(GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 levels, u32 layers)
|
||||
NonnullRefPtr<GPU::Image> Device::create_image(GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 max_levels)
|
||||
{
|
||||
VERIFY(width > 0);
|
||||
VERIFY(height > 0);
|
||||
VERIFY(depth > 0);
|
||||
VERIFY(levels > 0);
|
||||
VERIFY(layers > 0);
|
||||
VERIFY(max_levels > 0);
|
||||
|
||||
return adopt_ref(*new Image(this, pixel_format, width, height, depth, levels, layers));
|
||||
return adopt_ref(*new Image(this, pixel_format, width, height, depth, max_levels));
|
||||
}
|
||||
|
||||
void Device::set_sampler_config(unsigned sampler, GPU::SamplerConfig const& config)
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
virtual GPU::RasterizerOptions options() const override { return m_options; }
|
||||
virtual GPU::LightModelParameters light_model() const override { return m_lighting_model; }
|
||||
|
||||
virtual NonnullRefPtr<GPU::Image> create_image(GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 levels, u32 layers) override;
|
||||
virtual NonnullRefPtr<GPU::Image> create_image(GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels) override;
|
||||
|
||||
virtual void set_sampler_config(unsigned, GPU::SamplerConfig const&) override;
|
||||
virtual void set_light_state(unsigned, GPU::Light const&) override;
|
||||
|
@ -10,11 +10,10 @@
|
||||
|
||||
namespace SoftGPU {
|
||||
|
||||
Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 max_levels, u32 layers)
|
||||
Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 max_levels)
|
||||
: GPU::Image(ownership_token)
|
||||
, m_num_layers(layers)
|
||||
, m_pixel_format(pixel_format)
|
||||
, m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>>::must_create_but_fixme_should_propagate_errors(layers * max_levels))
|
||||
, m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>>::must_create_but_fixme_should_propagate_errors(max_levels))
|
||||
{
|
||||
VERIFY(pixel_format == GPU::PixelFormat::Alpha
|
||||
|| pixel_format == GPU::PixelFormat::Intensity
|
||||
@ -26,7 +25,6 @@ Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format,
|
||||
VERIFY(height > 0);
|
||||
VERIFY(depth > 0);
|
||||
VERIFY(max_levels > 0);
|
||||
VERIFY(layers > 0);
|
||||
|
||||
m_width_is_power_of_two = is_power_of_two(width);
|
||||
m_height_is_power_of_two = is_power_of_two(height);
|
||||
@ -34,8 +32,7 @@ Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format,
|
||||
|
||||
u32 level;
|
||||
for (level = 0; level < max_levels; ++level) {
|
||||
for (u32 layer = 0; layer < layers; ++layer)
|
||||
m_mipmap_buffers[layer * layers + level] = MUST(Typed3DBuffer<FloatVector4>::try_create(width, height, depth));
|
||||
m_mipmap_buffers[level] = MUST(Typed3DBuffer<FloatVector4>::try_create(width, height, depth));
|
||||
|
||||
if (width <= 1 && height <= 1 && depth <= 1)
|
||||
break;
|
||||
@ -77,13 +74,12 @@ GPU::ImageDataLayout Image::image_data_layout(u32 level, Vector3<i32> offset) co
|
||||
};
|
||||
}
|
||||
|
||||
void Image::write_texels(u32 layer, u32 level, Vector3<i32> const& output_offset, void const* input_data, GPU::ImageDataLayout const& input_layout)
|
||||
void Image::write_texels(u32 level, Vector3<i32> const& output_offset, void const* input_data, GPU::ImageDataLayout const& input_layout)
|
||||
{
|
||||
VERIFY(layer < num_layers());
|
||||
VERIFY(level < num_levels());
|
||||
|
||||
auto output_layout = image_data_layout(level, output_offset);
|
||||
auto texel_data = texel_pointer(layer, level, 0, 0, 0);
|
||||
auto texel_data = texel_pointer(level, 0, 0, 0);
|
||||
|
||||
PixelConverter converter { input_layout, output_layout };
|
||||
ErrorOr<void> conversion_result;
|
||||
@ -100,31 +96,28 @@ void Image::write_texels(u32 layer, u32 level, Vector3<i32> const& output_offset
|
||||
dbgln("Pixel conversion failed: {}", conversion_result.error().string_literal());
|
||||
}
|
||||
|
||||
void Image::read_texels(u32 layer, u32 level, Vector3<i32> const& input_offset, void* output_data, GPU::ImageDataLayout const& output_layout) const
|
||||
void Image::read_texels(u32 level, Vector3<i32> const& input_offset, void* output_data, GPU::ImageDataLayout const& output_layout) const
|
||||
{
|
||||
VERIFY(layer < num_layers());
|
||||
VERIFY(level < num_levels());
|
||||
|
||||
auto input_layout = image_data_layout(level, input_offset);
|
||||
|
||||
PixelConverter converter { input_layout, output_layout };
|
||||
auto conversion_result = converter.convert(texel_pointer(layer, level, 0, 0, 0), output_data, {});
|
||||
auto conversion_result = converter.convert(texel_pointer(level, 0, 0, 0), output_data, {});
|
||||
if (conversion_result.is_error())
|
||||
dbgln("Pixel conversion failed: {}", conversion_result.error().string_literal());
|
||||
}
|
||||
|
||||
void Image::copy_texels(GPU::Image const& source, u32 source_layer, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_layer, u32 destination_level, Vector3<u32> const& destination_offset)
|
||||
void Image::copy_texels(GPU::Image const& source, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_level, Vector3<u32> const& destination_offset)
|
||||
{
|
||||
VERIFY(source.has_same_ownership_token(*this));
|
||||
|
||||
auto const& src_image = static_cast<Image const&>(source);
|
||||
|
||||
VERIFY(source_layer < src_image.num_layers());
|
||||
VERIFY(source_level < src_image.num_levels());
|
||||
VERIFY(source_offset.x() + size.x() <= src_image.level_width(source_level));
|
||||
VERIFY(source_offset.y() + size.y() <= src_image.level_height(source_level));
|
||||
VERIFY(source_offset.z() + size.z() <= src_image.level_depth(source_level));
|
||||
VERIFY(destination_layer < num_layers());
|
||||
VERIFY(destination_level < num_levels());
|
||||
VERIFY(destination_offset.x() + size.x() <= level_width(destination_level));
|
||||
VERIFY(destination_offset.y() + size.y() <= level_height(destination_level));
|
||||
@ -133,8 +126,8 @@ void Image::copy_texels(GPU::Image const& source, u32 source_layer, u32 source_l
|
||||
for (u32 z = 0; z < size.z(); ++z) {
|
||||
for (u32 y = 0; y < size.y(); ++y) {
|
||||
for (u32 x = 0; x < size.x(); ++x) {
|
||||
auto color = src_image.texel(source_layer, source_level, source_offset.x() + x, source_offset.y() + y, source_offset.z() + z);
|
||||
set_texel(destination_layer, destination_level, destination_offset.x() + x, destination_offset.y() + y, destination_offset.z() + z, color);
|
||||
auto color = src_image.texel(source_level, source_offset.x() + x, source_offset.y() + y, source_offset.z() + z);
|
||||
set_texel(destination_level, destination_offset.x() + x, destination_offset.y() + y, destination_offset.z() + z, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,46 +20,44 @@ namespace SoftGPU {
|
||||
|
||||
class Image final : public GPU::Image {
|
||||
public:
|
||||
Image(void const* ownership_token, GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels, u32 layers);
|
||||
Image(void const* ownership_token, GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels);
|
||||
|
||||
u32 level_width(u32 level) const { return m_mipmap_buffers[level]->width(); }
|
||||
u32 level_height(u32 level) const { return m_mipmap_buffers[level]->height(); }
|
||||
u32 level_depth(u32 level) const { return m_mipmap_buffers[level]->depth(); }
|
||||
u32 num_levels() const { return m_num_levels; }
|
||||
u32 num_layers() const { return m_num_layers; }
|
||||
bool width_is_power_of_two() const { return m_width_is_power_of_two; }
|
||||
bool height_is_power_of_two() const { return m_height_is_power_of_two; }
|
||||
bool depth_is_power_of_two() const { return m_depth_is_power_of_two; }
|
||||
|
||||
GPU::ImageDataLayout image_data_layout(u32 level, Vector3<i32> offset) const;
|
||||
|
||||
FloatVector4 texel(u32 layer, u32 level, int x, int y, int z) const
|
||||
FloatVector4 texel(u32 level, int x, int y, int z) const
|
||||
{
|
||||
return *texel_pointer(layer, level, x, y, z);
|
||||
return *texel_pointer(level, x, y, z);
|
||||
}
|
||||
|
||||
void set_texel(u32 layer, u32 level, int x, int y, int z, FloatVector4 const& color)
|
||||
void set_texel(u32 level, int x, int y, int z, FloatVector4 const& color)
|
||||
{
|
||||
*texel_pointer(layer, level, x, y, z) = color;
|
||||
*texel_pointer(level, x, y, z) = color;
|
||||
}
|
||||
|
||||
virtual void write_texels(u32 layer, u32 level, Vector3<i32> const& output_offset, void const* input_data, GPU::ImageDataLayout const&) override;
|
||||
virtual void read_texels(u32 layer, u32 level, Vector3<i32> const& input_offset, void* output_data, GPU::ImageDataLayout const&) const override;
|
||||
virtual void copy_texels(GPU::Image const& source, u32 source_layer, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_layer, u32 destination_level, Vector3<u32> const& destination_offset) override;
|
||||
virtual void write_texels(u32 level, Vector3<i32> const& output_offset, void const* input_data, GPU::ImageDataLayout const&) override;
|
||||
virtual void read_texels(u32 level, Vector3<i32> const& input_offset, void* output_data, GPU::ImageDataLayout const&) const override;
|
||||
virtual void copy_texels(GPU::Image const& source, u32 source_level, Vector3<u32> const& source_offset, Vector3<u32> const& size, u32 destination_level, Vector3<u32> const& destination_offset) override;
|
||||
|
||||
FloatVector4 const* texel_pointer(u32 layer, u32 level, int x, int y, int z) const
|
||||
FloatVector4 const* texel_pointer(u32 level, int x, int y, int z) const
|
||||
{
|
||||
return m_mipmap_buffers[layer * m_num_layers + level]->buffer_pointer(x, y, z);
|
||||
return m_mipmap_buffers[level]->buffer_pointer(x, y, z);
|
||||
}
|
||||
|
||||
FloatVector4* texel_pointer(u32 layer, u32 level, int x, int y, int z)
|
||||
FloatVector4* texel_pointer(u32 level, int x, int y, int z)
|
||||
{
|
||||
return m_mipmap_buffers[layer * m_num_layers + level]->buffer_pointer(x, y, z);
|
||||
return m_mipmap_buffers[level]->buffer_pointer(x, y, z);
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_num_levels { 0 };
|
||||
u32 m_num_layers { 0 };
|
||||
|
||||
GPU::PixelFormat m_pixel_format;
|
||||
FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>> m_mipmap_buffers;
|
||||
|
@ -71,12 +71,12 @@ static f32x4 wrap(f32x4 value, GPU::TextureWrapMode mode, f32x4 num_texels)
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static Vector4<f32x4> texel4(Image const& image, u32x4 layer, u32x4 level, u32x4 x, u32x4 y, u32x4 z)
|
||||
ALWAYS_INLINE static Vector4<f32x4> texel4(Image const& image, u32x4 level, u32x4 x, u32x4 y, u32x4 z)
|
||||
{
|
||||
auto t0 = image.texel(layer[0], level[0], x[0], y[0], z[0]);
|
||||
auto t1 = image.texel(layer[1], level[1], x[1], y[1], z[1]);
|
||||
auto t2 = image.texel(layer[2], level[2], x[2], y[2], z[2]);
|
||||
auto t3 = image.texel(layer[3], level[3], x[3], y[3], z[3]);
|
||||
auto t0 = image.texel(level[0], x[0], y[0], z[0]);
|
||||
auto t1 = image.texel(level[1], x[1], y[1], z[1]);
|
||||
auto t2 = image.texel(level[2], x[2], y[2], z[2]);
|
||||
auto t3 = image.texel(level[3], x[3], y[3], z[3]);
|
||||
|
||||
return Vector4<f32x4> {
|
||||
f32x4 { t0.x(), t1.x(), t2.x(), t3.x() },
|
||||
@ -86,14 +86,14 @@ ALWAYS_INLINE static Vector4<f32x4> texel4(Image const& image, u32x4 layer, u32x
|
||||
};
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static Vector4<f32x4> texel4border(Image const& image, u32x4 layer, u32x4 level, u32x4 x, u32x4 y, u32x4 z, FloatVector4 const& border, u32x4 w, u32x4 h)
|
||||
ALWAYS_INLINE static Vector4<f32x4> texel4border(Image const& image, u32x4 level, u32x4 x, u32x4 y, u32x4 z, FloatVector4 const& border, u32x4 w, u32x4 h)
|
||||
{
|
||||
auto border_mask = maskbits(x < 0 || x >= w || y < 0 || y >= h);
|
||||
|
||||
auto t0 = border_mask & 1 ? border : image.texel(layer[0], level[0], x[0], y[0], z[0]);
|
||||
auto t1 = border_mask & 2 ? border : image.texel(layer[1], level[1], x[1], y[1], z[1]);
|
||||
auto t2 = border_mask & 4 ? border : image.texel(layer[2], level[2], x[2], y[2], z[2]);
|
||||
auto t3 = border_mask & 8 ? border : image.texel(layer[3], level[3], x[3], y[3], z[3]);
|
||||
auto t0 = border_mask & 1 ? border : image.texel(level[0], x[0], y[0], z[0]);
|
||||
auto t1 = border_mask & 2 ? border : image.texel(level[1], x[1], y[1], z[1]);
|
||||
auto t2 = border_mask & 4 ? border : image.texel(level[2], x[2], y[2], z[2]);
|
||||
auto t3 = border_mask & 8 ? border : image.texel(level[3], x[3], y[3], z[3]);
|
||||
|
||||
return Vector4<f32x4> {
|
||||
f32x4 { t0.x(), t1.x(), t2.x(), t3.x() },
|
||||
@ -155,7 +155,6 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv)
|
||||
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 = *static_ptr_cast<Image>(m_config.bound_image);
|
||||
u32x4 const layer = expand4(0u);
|
||||
|
||||
u32x4 const width = {
|
||||
image.level_width(level[0]),
|
||||
@ -187,7 +186,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const&
|
||||
i = image.width_is_power_of_two() ? i & width_mask : i % width;
|
||||
j = image.height_is_power_of_two() ? j & height_mask : j % height;
|
||||
|
||||
return texel4(image, layer, level, i, j, k);
|
||||
return texel4(image, level, i, j, k);
|
||||
}
|
||||
|
||||
u -= 0.5f;
|
||||
@ -223,15 +222,15 @@ 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 == 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);
|
||||
t3 = texel4(image, layer, level, i1, j1, k);
|
||||
t0 = texel4(image, level, i0, j0, k);
|
||||
t1 = texel4(image, level, i1, j0, k);
|
||||
t2 = texel4(image, level, i0, j1, k);
|
||||
t3 = texel4(image, level, i1, j1, k);
|
||||
} else {
|
||||
t1 = texel4border(image, layer, level, i1, j0, k, m_config.border_color, width, height);
|
||||
t0 = texel4border(image, layer, level, i0, j0, k, m_config.border_color, width, height);
|
||||
t2 = texel4border(image, layer, level, i0, j1, k, m_config.border_color, width, height);
|
||||
t3 = texel4border(image, layer, level, i1, j1, k, m_config.border_color, width, height);
|
||||
t1 = texel4border(image, level, i1, j0, k, m_config.border_color, width, height);
|
||||
t0 = texel4border(image, level, i0, j0, k, m_config.border_color, width, height);
|
||||
t2 = texel4border(image, level, i0, j1, k, m_config.border_color, width, height);
|
||||
t3 = texel4border(image, level, i1, j1, k, m_config.border_color, width, height);
|
||||
}
|
||||
|
||||
f32x4 const alpha = frac_int_range(u);
|
||||
|
Loading…
Reference in New Issue
Block a user