mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-10 15:38:08 +01:00
Improve scaling and separate sampler state from texture state
This commit is contained in:
parent
604e42bde8
commit
fe0600866c
|
|
@ -397,6 +397,7 @@ void GLGSRender::end()
|
|||
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
|
||||
|
||||
//Setup textures
|
||||
//Setting unused texture to 0 is not needed, but makes program validation happy if we choose to enforce it
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
int location;
|
||||
|
|
@ -411,6 +412,7 @@ void GLGSRender::end()
|
|||
{
|
||||
m_gl_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.fragment_textures[i]));
|
||||
__glcheck m_gl_texture_cache.upload_texture(i, rsx::method_registers.fragment_textures[i], m_gl_textures[i], m_rtts);
|
||||
__glcheck m_gl_sampler_states[i].apply(rsx::method_registers.fragment_textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -561,6 +563,12 @@ void GLGSRender::on_init_thread()
|
|||
if (g_cfg_rsx_overlay)
|
||||
m_text_printer.init();
|
||||
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
m_gl_sampler_states[i].create();
|
||||
m_gl_sampler_states[i].bind(i);
|
||||
}
|
||||
|
||||
m_gl_texture_cache.initialize(this);
|
||||
}
|
||||
|
||||
|
|
@ -595,6 +603,11 @@ void GLGSRender::on_exit()
|
|||
tex.remove();
|
||||
}
|
||||
|
||||
for (auto &sampler : m_gl_sampler_states)
|
||||
{
|
||||
sampler.remove();
|
||||
}
|
||||
|
||||
m_attrib_ring_buffer->remove();
|
||||
m_transform_constants_buffer->remove();
|
||||
m_fragment_constants_buffer->remove();
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ private:
|
|||
|
||||
rsx::gl::texture m_gl_textures[rsx::limits::fragment_textures_count];
|
||||
rsx::gl::texture m_gl_vertex_textures[rsx::limits::vertex_textures_count];
|
||||
gl::sampler_state m_gl_sampler_states[rsx::limits::fragment_textures_count];
|
||||
|
||||
gl::glsl::program *m_program;
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,13 @@ OPENGL_PROC(PFNGLMULTIDRAWARRAYSPROC, MultiDrawArrays);
|
|||
|
||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
||||
|
||||
//Sampler Objects
|
||||
OPENGL_PROC(PFNGLGENSAMPLERSPROC, GenSamplers);
|
||||
OPENGL_PROC(PFNGLDELETESAMPLERSPROC, DeleteSamplers);
|
||||
OPENGL_PROC(PFNGLBINDSAMPLERPROC, BindSampler);
|
||||
OPENGL_PROC(PFNGLSAMPLERPARAMETERIPROC, SamplerParameteri);
|
||||
OPENGL_PROC(PFNGLSAMPLERPARAMETERFVPROC, SamplerParameterfv);
|
||||
|
||||
//Texture Buffers
|
||||
OPENGL_PROC(PFNGLTEXBUFFERPROC, TexBuffer);
|
||||
OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEEXTPROC, TextureBufferRangeEXT);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,54 @@ namespace gl
|
|||
}
|
||||
fmt::throw_exception("Compressed or unknown texture format 0x%x" HERE, texture_format);
|
||||
}
|
||||
|
||||
GLenum wrap_mode(rsx::texture_wrap_mode wrap)
|
||||
{
|
||||
switch (wrap)
|
||||
{
|
||||
case rsx::texture_wrap_mode::wrap: return GL_REPEAT;
|
||||
case rsx::texture_wrap_mode::mirror: return GL_MIRRORED_REPEAT;
|
||||
case rsx::texture_wrap_mode::clamp_to_edge: return GL_CLAMP_TO_EDGE;
|
||||
case rsx::texture_wrap_mode::border: return GL_CLAMP_TO_BORDER;
|
||||
case rsx::texture_wrap_mode::clamp: return GL_CLAMP_TO_BORDER;
|
||||
case rsx::texture_wrap_mode::mirror_once_clamp_to_edge: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
|
||||
case rsx::texture_wrap_mode::mirror_once_border: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
|
||||
case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT;
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d)", (u32)wrap);
|
||||
return GL_REPEAT;
|
||||
}
|
||||
|
||||
float max_aniso(rsx::texture_max_anisotropy aniso)
|
||||
{
|
||||
switch (aniso)
|
||||
{
|
||||
case rsx::texture_max_anisotropy::x1: return 1.0f;
|
||||
case rsx::texture_max_anisotropy::x2: return 2.0f;
|
||||
case rsx::texture_max_anisotropy::x4: return 4.0f;
|
||||
case rsx::texture_max_anisotropy::x6: return 6.0f;
|
||||
case rsx::texture_max_anisotropy::x8: return 8.0f;
|
||||
case rsx::texture_max_anisotropy::x10: return 10.0f;
|
||||
case rsx::texture_max_anisotropy::x12: return 12.0f;
|
||||
case rsx::texture_max_anisotropy::x16: return 16.0f;
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d)", (u32)aniso);
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//Apply sampler state settings
|
||||
void sampler_state::apply(rsx::fragment_texture& tex)
|
||||
{
|
||||
const f32 border_color = (f32)tex.border_color() / 255;
|
||||
const f32 border_color_array[] = { border_color, border_color, border_color, border_color };
|
||||
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s()));
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t()));
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r()));
|
||||
glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color_array);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -230,42 +278,6 @@ namespace rsx
|
|||
glGenTextures(1, &m_id);
|
||||
}
|
||||
|
||||
int texture::gl_wrap(rsx::texture_wrap_mode wrap)
|
||||
{
|
||||
switch (wrap)
|
||||
{
|
||||
case rsx::texture_wrap_mode::wrap: return GL_REPEAT;
|
||||
case rsx::texture_wrap_mode::mirror: return GL_MIRRORED_REPEAT;
|
||||
case rsx::texture_wrap_mode::clamp_to_edge: return GL_CLAMP_TO_EDGE;
|
||||
case rsx::texture_wrap_mode::border: return GL_CLAMP_TO_BORDER;
|
||||
case rsx::texture_wrap_mode::clamp: return GL_CLAMP_TO_BORDER;
|
||||
case rsx::texture_wrap_mode::mirror_once_clamp_to_edge: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
|
||||
case rsx::texture_wrap_mode::mirror_once_border: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
|
||||
case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT;
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d)", (u32)wrap);
|
||||
return GL_REPEAT;
|
||||
}
|
||||
|
||||
float texture::max_aniso(rsx::texture_max_anisotropy aniso)
|
||||
{
|
||||
switch (aniso)
|
||||
{
|
||||
case rsx::texture_max_anisotropy::x1: return 1.0f;
|
||||
case rsx::texture_max_anisotropy::x2: return 2.0f;
|
||||
case rsx::texture_max_anisotropy::x4: return 4.0f;
|
||||
case rsx::texture_max_anisotropy::x6: return 6.0f;
|
||||
case rsx::texture_max_anisotropy::x8: return 8.0f;
|
||||
case rsx::texture_max_anisotropy::x10: return 10.0f;
|
||||
case rsx::texture_max_anisotropy::x12: return 12.0f;
|
||||
case rsx::texture_max_anisotropy::x16: return 16.0f;
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d)", (u32)aniso);
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
u16 texture::get_pitch_modifier(u32 format)
|
||||
{
|
||||
switch (format)
|
||||
|
|
@ -431,8 +443,8 @@ namespace rsx
|
|||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void texture::init(int index, rsx::fragment_texture& tex)
|
||||
{
|
||||
switch (tex.dimension())
|
||||
|
|
@ -527,9 +539,9 @@ namespace rsx
|
|||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, remap_values[2]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, remap_values[3]);
|
||||
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_S, ::gl::wrap_mode(tex.wrap_s()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, ::gl::wrap_mode(tex.wrap_t()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_R, ::gl::wrap_mode(tex.wrap_r()));
|
||||
|
||||
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
|
||||
{
|
||||
|
|
@ -569,7 +581,7 @@ namespace rsx
|
|||
}
|
||||
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter(tex.mag_filter()));
|
||||
__glcheck glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
|
||||
__glcheck glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, ::gl::max_aniso(tex.max_aniso()));
|
||||
}
|
||||
|
||||
void texture::init(int index, rsx::vertex_texture& tex)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,42 @@ namespace rsx
|
|||
{
|
||||
class vertex_texture;
|
||||
class fragment_texture;
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
GLenum get_sized_internal_format(u32 gcm_format);
|
||||
std::tuple<GLenum, GLenum> get_format_type(u32 texture_format);
|
||||
GLenum wrap_mode(rsx::texture_wrap_mode wrap);
|
||||
float max_aniso(rsx::texture_max_anisotropy aniso);
|
||||
|
||||
class sampler_state
|
||||
{
|
||||
GLuint samplerHandle = 0;
|
||||
|
||||
public:
|
||||
|
||||
void create()
|
||||
{
|
||||
glGenSamplers(1, &samplerHandle);
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
glDeleteSamplers(1, &samplerHandle);
|
||||
}
|
||||
|
||||
void bind(int index)
|
||||
{
|
||||
glBindSampler(index, samplerHandle);
|
||||
}
|
||||
|
||||
void apply(rsx::fragment_texture& tex);
|
||||
};
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace gl
|
||||
{
|
||||
class texture
|
||||
|
|
@ -16,28 +51,6 @@ namespace rsx
|
|||
public:
|
||||
void create();
|
||||
|
||||
int gl_wrap(rsx::texture_wrap_mode in);
|
||||
|
||||
float max_aniso(rsx::texture_max_anisotropy aniso);
|
||||
|
||||
inline static u8 convert_4_to_8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00001234 -> 12341234
|
||||
return (v << 4) | (v);
|
||||
}
|
||||
|
||||
inline static u8 convert_5_to_8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00012345 -> 12345123
|
||||
return (v << 3) | (v >> 2);
|
||||
}
|
||||
|
||||
inline static u8 convert_6_to_8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00123456 -> 12345612
|
||||
return (v << 2) | (v >> 4);
|
||||
}
|
||||
|
||||
void init(int index, rsx::fragment_texture& tex);
|
||||
void init(int index, rsx::vertex_texture& tex);
|
||||
|
||||
|
|
@ -64,9 +77,3 @@ namespace rsx
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
GLenum get_sized_internal_format(u32 gcm_format);
|
||||
std::tuple<GLenum, GLenum> get_format_type(u32 texture_format);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1073,7 +1073,7 @@ namespace gl
|
|||
const u32 dst_address = (u32)((u64)dst.pixels - (u64)vm::base(0));
|
||||
|
||||
//Check if src/dst are parts of render targets
|
||||
surface_subresource src_subres = m_rtts.get_surface_subresource_if_applicable(src_address, src.width, src.slice_h, src.pitch, true, true);
|
||||
surface_subresource src_subres = m_rtts.get_surface_subresource_if_applicable(src_address, src.width, src.height, src.pitch, true, true);
|
||||
src_is_render_target = src_subres.surface != nullptr;
|
||||
|
||||
//Prepare areas and offsets
|
||||
|
|
|
|||
Loading…
Reference in a new issue