Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsx: Reimplement texture border colors #16169

Merged
merged 7 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions rpcs3/Emu/RSX/Common/TextureUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1440,17 +1440,18 @@ namespace rsx
texture.border_type() ^ 1);
}

u32 get_remap_encoding(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
u32 get_remap_encoding(const texture_channel_remap_t& remap)
{
u32 encode = 0;
encode |= (remap.first[0] << 0);
encode |= (remap.first[1] << 2);
encode |= (remap.first[2] << 4);
encode |= (remap.first[3] << 6);
encode |= (remap.second[0] << 8);
encode |= (remap.second[1] << 10);
encode |= (remap.second[2] << 12);
encode |= (remap.second[3] << 14);
encode |= (remap.channel_map[0] << 0);
encode |= (remap.channel_map[1] << 2);
encode |= (remap.channel_map[2] << 4);
encode |= (remap.channel_map[3] << 6);

encode |= (remap.control_map[0] << 8);
encode |= (remap.control_map[1] << 10);
encode |= (remap.control_map[2] << 12);
encode |= (remap.control_map[3] << 14);
return encode;
}

Expand Down Expand Up @@ -1571,4 +1572,25 @@ namespace rsx
return true;
}
}

bool is_border_clamped_texture(
rsx::texture_wrap_mode wrap_s,
rsx::texture_wrap_mode wrap_t,
rsx::texture_wrap_mode wrap_r,
rsx::texture_dimension dimension)
{
// Technically we should check border and mirror_once_border
// However, the latter is not implemented in any modern API, so we can just ignore it (emulated with mirror_once_clamp).
switch (dimension)
{
case rsx::texture_dimension::dimension1d:
return wrap_s == rsx::texture_wrap_mode::border;
case rsx::texture_dimension::dimension2d:
return wrap_s == rsx::texture_wrap_mode::border || wrap_t == rsx::texture_wrap_mode::border;
case rsx::texture_dimension::dimension3d:
return wrap_s == rsx::texture_wrap_mode::border || wrap_t == rsx::texture_wrap_mode::border || wrap_r == rsx::texture_wrap_mode::border;
default:
return false;
}
}
}
10 changes: 9 additions & 1 deletion rpcs3/Emu/RSX/Common/TextureUtils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "io_buffer.h"
#include "../color_utils.h"
#include "../RSXTexture.h"

#include <span>
Expand Down Expand Up @@ -276,7 +277,7 @@ namespace rsx
/**
* Reverse encoding
*/
u32 get_remap_encoding(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap);
u32 get_remap_encoding(const texture_channel_remap_t& remap);

/**
* Get gcm texel layout. Returns <format, byteswapped>
Expand All @@ -288,4 +289,11 @@ namespace rsx
format_class classify_format(u32 gcm_format);

bool is_texcoord_wrapping_mode(rsx::texture_wrap_mode mode);
bool is_border_clamped_texture(rsx::texture_wrap_mode wrap_s, rsx::texture_wrap_mode wrap_t, rsx::texture_wrap_mode wrap_r, rsx::texture_dimension dimension);

template <typename TextureType>
bool is_border_clamped_texture(const TextureType& tex)
{
return is_border_clamped_texture(tex.wrap_s(), tex.wrap_t(), tex.wrap_r(), tex.dimension());
}
}
22 changes: 10 additions & 12 deletions rpcs3/Emu/RSX/Common/texture_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1837,7 +1837,6 @@ namespace rsx
commandbuffer_type& cmd,
const image_section_attributes_t& attr,
const size3f& scale,
u32 encoded_remap,
const texture_channel_remap_t& remap,
const texture_cache_search_options& options,
const utils::address_range& memory_range,
Expand All @@ -1849,7 +1848,7 @@ namespace rsx
// Most mesh textures are stored as compressed to make the most of the limited memory
if (auto cached_texture = find_texture_from_dimensions(attr.address, attr.gcm_format, attr.width, attr.height, attr.depth))
{
return{ cached_texture->get_view(encoded_remap, remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() };
return{ cached_texture->get_view(remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() };
}
}
else
Expand All @@ -1863,7 +1862,7 @@ namespace rsx
const bool force_convert = !render_target_format_is_compatible(texptr, attr.gcm_format);

auto result = helpers::process_framebuffer_resource_fast<sampled_image_descriptor>(
cmd, texptr, attr, scale, extended_dimension, encoded_remap, remap, true, force_convert);
cmd, texptr, attr, scale, extended_dimension, remap, true, force_convert);

if (!options.skip_texture_barriers && result.is_cyclic_reference)
{
Expand All @@ -1887,7 +1886,7 @@ namespace rsx
const bool force_convert = !render_target_format_is_compatible(last.surface, attr.gcm_format);

return helpers::process_framebuffer_resource_fast<sampled_image_descriptor>(
cmd, last.surface, attr, scale, extended_dimension, encoded_remap, remap, false, force_convert);
cmd, last.surface, attr, scale, extended_dimension, remap, false, force_convert);
}

return {};
Expand Down Expand Up @@ -1941,7 +1940,7 @@ namespace rsx
break;
}

return{ cached_texture->get_view(encoded_remap, remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() };
return{ cached_texture->get_view(remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() };
}
}

Expand Down Expand Up @@ -2016,7 +2015,7 @@ namespace rsx
{
// Clipped view
auto viewed_image = last->get_raw_texture();
sampled_image_descriptor result = { viewed_image->get_view(encoded_remap, remap), last->get_context(),
sampled_image_descriptor result = { viewed_image->get_view(remap), last->get_context(),
viewed_image->format_class(), scale, extended_dimension, false, viewed_image->samples() };

helpers::calculate_sample_clip_parameters(result, position2i(0, 0), size2i(attr.width, attr.height), size2i(normalized_width, last->get_height()));
Expand All @@ -2029,7 +2028,7 @@ namespace rsx
}

auto result = helpers::merge_cache_resources<sampled_image_descriptor>(
cmd, overlapping_fbos, overlapping_locals, attr, scale, extended_dimension, encoded_remap, remap, _pool);
cmd, overlapping_fbos, overlapping_locals, attr, scale, extended_dimension, remap, _pool);

const bool is_simple_subresource_copy =
(result.external_subresource_desc.op == deferred_request_command::copy_image_static) ||
Expand All @@ -2048,13 +2047,12 @@ namespace rsx
position2i(result.external_subresource_desc.x, result.external_subresource_desc.y),
size2i(result.external_subresource_desc.width, result.external_subresource_desc.height),
size2i(result.external_subresource_desc.external_handle->width(), result.external_subresource_desc.external_handle->height()),
encoded_remap, remap, false);
remap, false);
}
else
{
helpers::convert_image_blit_to_clip_descriptor(
result,
encoded_remap,
remap,
false);
}
Expand Down Expand Up @@ -2348,7 +2346,7 @@ namespace rsx
const auto lookup_range = utils::address_range::start_length(attributes.address, attributes.pitch * required_surface_height);
reader_lock lock(m_cache_mutex);

auto result = fast_texture_search(cmd, attributes, scale, tex.remap(), tex.decoded_remap(),
auto result = fast_texture_search(cmd, attributes, scale, tex.decoded_remap(),
options, lookup_range, extended_dimension, m_rtts,
std::forward<Args>(extras)...);

Expand Down Expand Up @@ -2423,7 +2421,7 @@ namespace rsx
}

const auto range = utils::address_range::start_length(attr2.address, attr2.pitch * attr2.height);
auto ret = fast_texture_search(cmd, attr2, scale, tex.remap(), tex.decoded_remap(),
auto ret = fast_texture_search(cmd, attr2, scale, tex.decoded_remap(),
options, range, extended_dimension, m_rtts, std::forward<Args>(extras)...);

if (!ret.validate() ||
Expand Down Expand Up @@ -2488,7 +2486,7 @@ namespace rsx
auto uploaded = upload_image_from_cpu(cmd, tex_range, attributes.width, attributes.height, attributes.depth, tex.get_exact_mipmap_count(), attributes.pitch, attributes.gcm_format,
texture_upload_context::shader_read, subresources_layout, extended_dimension, attributes.swizzled);

return{ uploaded->get_view(tex.remap(), tex.decoded_remap()),
return{ uploaded->get_view(tex.decoded_remap()),
texture_upload_context::shader_read, format_class, scale, extended_dimension };
}

Expand Down
13 changes: 4 additions & 9 deletions rpcs3/Emu/RSX/Common/texture_cache_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

namespace rsx
{
using texture_channel_remap_t = std::pair<std::array<u8, 4>, std::array<u8, 4>>;

// Defines pixel operation to be performed on a surface before it is ready for use
enum surface_transform : u32
{
Expand Down Expand Up @@ -551,11 +549,10 @@ namespace rsx
const position2i& offset,
const size2i& desired_dimensions,
const size2i& actual_dimensions,
u32 encoded_remap,
const texture_channel_remap_t& decoded_remap,
bool cyclic_reference)
{
desc.image_handle = desc.external_subresource_desc.as_viewable()->get_view(encoded_remap, decoded_remap);
desc.image_handle = desc.external_subresource_desc.as_viewable()->get_view(decoded_remap);
desc.ref_address = desc.external_subresource_desc.external_ref_addr;
desc.is_cyclic_reference = cyclic_reference;
desc.samples = desc.external_subresource_desc.external_handle->samples();
Expand All @@ -567,7 +564,6 @@ namespace rsx
template <typename sampled_image_descriptor>
void convert_image_blit_to_clip_descriptor(
sampled_image_descriptor& desc,
u32 encoded_remap,
const texture_channel_remap_t& decoded_remap,
bool cyclic_reference)
{
Expand Down Expand Up @@ -602,7 +598,6 @@ namespace rsx
position2i(section.src_x, section.src_y),
size2i(section.src_w, section.src_h),
size2i(surface_width, surface_height),
encoded_remap,
decoded_remap,
cyclic_reference);
}
Expand All @@ -613,7 +608,7 @@ namespace rsx
const image_section_attributes_t& attr,
const size3f& scale,
texture_dimension_extended extended_dimension,
u32 encoded_remap, const texture_channel_remap_t& decoded_remap,
const texture_channel_remap_t& decoded_remap,
bool surface_is_rop_target,
bool force_convert)
{
Expand Down Expand Up @@ -710,7 +705,7 @@ namespace rsx

texptr->memory_barrier(cmd, access_type);
auto viewed_surface = texptr->get_surface(access_type);
sampled_image_descriptor result = { viewed_surface->get_view(encoded_remap, decoded_remap), texture_upload_context::framebuffer_storage,
sampled_image_descriptor result = { viewed_surface->get_view(decoded_remap), texture_upload_context::framebuffer_storage,
texptr->format_class(), scale, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target, viewed_surface->samples() };

if (requires_clip)
Expand Down Expand Up @@ -746,7 +741,7 @@ namespace rsx
const image_section_attributes_t& attr,
const size3f& scale,
texture_dimension_extended extended_dimension,
u32 /*encoded_remap*/, const texture_channel_remap_t& decoded_remap,
const texture_channel_remap_t& decoded_remap,
int select_hint = -1)
{
ensure((select_hint & 0x1) == select_hint);
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/RSX/GL/GLCompute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ namespace gl
m_program.uniforms["region_offset"] = color2i(region.x, region.y);
m_program.uniforms["region_size"] = color2i(region.width, region.height);

auto depth_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::depth);
auto stencil_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::stencil);
auto depth_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::depth);
auto stencil_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::stencil);

if (!m_sampler)
{
Expand Down Expand Up @@ -396,7 +396,7 @@ namespace gl
m_program.uniforms["is_bgra"] = (layout.format == static_cast<GLenum>(gl::texture::format::bgra));
m_program.uniforms["block_width"] = static_cast<u32>(layout.size);

auto data_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::color);
auto data_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::color);

if (!m_sampler)
{
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/GL/GLDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ void GLGSRender::bind_texture_env()
if (current_fragment_program.texture_state.redirected_textures & (1 << i))
{
auto root_texture = static_cast<gl::viewable_image*>(view->image());
auto stencil_view = root_texture->get_view(gl::GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::stencil);
auto stencil_view = root_texture->get_view(rsx::default_remap_vector.with_encoding(gl::GL_REMAP_IDENTITY), gl::image_aspect::stencil);
stencil_view->bind(cmd, GL_STENCIL_MIRRORS_START + i);
}
}
Expand Down
32 changes: 2 additions & 30 deletions rpcs3/Emu/RSX/GL/GLTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,37 +807,9 @@ namespace gl
}
}

std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap)
std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const rsx::texture_channel_remap_t& decoded_remap)
{
//Remapping tables; format is A-R-G-B
//Remap input table. Contains channel index to read color from
const auto remap_inputs = decoded_remap.first;

//Remap control table. Controls whether the remap value is used, or force either 0 or 1
const auto remap_lookup = decoded_remap.second;

std::array<GLenum, 4> remap_values;

for (u8 channel = 0; channel < 4; ++channel)
{
switch (remap_lookup[channel])
{
default:
rsx_log.error("Unknown remap function 0x%X", remap_lookup[channel]);
[[fallthrough]];
case CELL_GCM_TEXTURE_REMAP_REMAP:
remap_values[channel] = swizzle_remap[remap_inputs[channel]];
break;
case CELL_GCM_TEXTURE_REMAP_ZERO:
remap_values[channel] = GL_ZERO;
break;
case CELL_GCM_TEXTURE_REMAP_ONE:
remap_values[channel] = GL_ONE;
break;
}
}

return remap_values;
return decoded_remap.remap<GLenum>(swizzle_remap, GL_ZERO, GL_ONE);
}

void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector<rsx::subresource_layout>& subresources_layout)
Expand Down
3 changes: 1 addition & 2 deletions rpcs3/Emu/RSX/GL/GLTextureCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ namespace gl
dst->set_native_component_layout(components);
}

const auto encoding = rsx::get_remap_encoding(remap);
return dst->get_view(encoding, remap);
return dst->get_view(remap);
}

void texture_cache::copy_transfer_regions_impl(gl::command_context& cmd, gl::texture* dst_image, const std::vector<copy_region_descriptor>& sources) const
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/RSX/GL/GLTextureCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,9 @@ namespace gl
return format;
}

gl::texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
gl::texture_view* get_view(const rsx::texture_channel_remap_t& remap)
{
return vram_texture->get_view(remap_encoding, remap);
return vram_texture->get_view(remap);
}

gl::viewable_image* get_raw_texture() const
Expand All @@ -402,7 +402,7 @@ namespace gl

gl::texture_view* get_raw_view()
{
return vram_texture->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector);
return vram_texture->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY));
}

bool is_depth_texture() const
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/RSX/GL/glutils/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,13 @@ namespace gl
m_id = GL_NONE;
}

texture_view* viewable_image::get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_, GLenum aspect_flags)
texture_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap_, GLenum aspect_flags)
{
auto remap = remap_;
const u64 view_aspect = static_cast<u64>(aspect_flags) & aspect();
ensure(view_aspect);

const u64 key = static_cast<u64>(remap_encoding) | (view_aspect << 32);
const u64 key = static_cast<u64>(remap.encoded) | (view_aspect << 32);
if (auto found = views.find(key);
found != views.end())
{
Expand All @@ -323,7 +323,7 @@ namespace gl
std::array<GLenum, 4> mapping;
GLenum* swizzle = nullptr;

if (remap_encoding != GL_REMAP_IDENTITY)
if (remap.encoded != GL_REMAP_IDENTITY)
{
mapping = apply_swizzle_remap(get_native_component_layout(), remap);
swizzle = mapping.data();
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/GL/glutils/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,10 @@ namespace gl
public:
using texture::texture;

texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap, GLenum aspect_flags = image_aspect::color | image_aspect::depth);
texture_view* get_view(const rsx::texture_channel_remap_t& remap, GLenum aspect_flags = image_aspect::color | image_aspect::depth);
void set_native_component_layout(const std::array<GLenum, 4>& layout);
};

// Texture helpers
std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap);
std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const rsx::texture_channel_remap_t& decoded_remap);
}
Loading