fixed CELL_GCM_TEXTURE_R5G6B5 & CELL_GCM_TEXTURE_R6G5B5 formats decoding

improved aa surface support
minor fixes
This commit is contained in:
DHrpcs3 2016-03-11 22:01:04 +03:00
parent 4d429ca918
commit 44341895ae
5 changed files with 159 additions and 189 deletions

View file

@ -136,6 +136,8 @@ extern CellGcmContextData current_context;
void GLGSRender::begin()
{
//LOG_NOTICE(RSX, "begin()");
rsx::thread::begin();
if (!load_program())
@ -420,6 +422,8 @@ namespace
void GLGSRender::end()
{
//LOG_NOTICE(RSX, "end()");
if (!draw_fbo)
{
rsx::thread::end();
@ -448,7 +452,7 @@ void GLGSRender::end()
std::vector<u8> vertex_arrays_data;
u32 vertex_arrays_offsets[rsx::limits::vertex_count];
const std::string reg_table[] =
static const std::string reg_table[] =
{
"in_pos", "in_weight", "in_normal",
"in_diff_color", "in_spec_color",
@ -513,7 +517,7 @@ void GLGSRender::end()
if (!vertex_info.size) // disabled, bind a null sampler
{
__glcheck glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count);
__glcheck glBindTexture(GL_TEXTURE_BUFFER, NULL);
__glcheck glBindTexture(GL_TEXTURE_BUFFER, 0);
__glcheck glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count);
continue;
}
@ -625,7 +629,7 @@ void GLGSRender::end()
auto& attrib_pair = m_gl_attrib_buffers[index];
attrib_pair.buffer.data(vertex_array.size(), vertex_array.data());
attrib_pair.buffer.data(element_size * vertex_draw_count, vertex_array.data());
//Attach buffer to texture
attrib_pair.texture.copy_from(attrib_pair.buffer, gl_type);
@ -714,15 +718,15 @@ void GLGSRender::set_viewport()
u16 viewport_x = viewport_horizontal & 0xffff;
u16 viewport_y = viewport_vertical & 0xffff;
u16 viewport_w = viewport_horizontal >> 16;
u16 viewport_h = viewport_vertical >> 16;
u16 viewport_w = (viewport_horizontal >> 16) * m_surface.width_mult;
u16 viewport_h = (viewport_vertical >> 16) * m_surface.height_mult;
u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL];
u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL];
u16 scissor_x = scissor_horizontal;
u16 scissor_w = scissor_horizontal >> 16;
u16 scissor_w = (scissor_horizontal >> 16) * m_surface.width_mult;
u16 scissor_y = scissor_vertical;
u16 scissor_h = scissor_vertical >> 16;
u16 scissor_h = (scissor_vertical >> 16) * m_surface.width_mult;
u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
@ -827,7 +831,7 @@ void GLGSRender::on_exit()
void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
{
//LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg);
//LOG_NOTICE(RSX, "nv4097_clear_surface(0x%x)", arg);
enum
{
@ -856,7 +860,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
GLbitfield mask = 0;
if (arg & depth_stencil)
if (renderer->cached_depth_buffer && (arg & depth_stencil))
{
if (arg & depth)
{
@ -865,8 +869,8 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8;
glDepthMask(GL_TRUE);
glClearDepth(double(clear_depth) / max_depth_value);
__glcheck glDepthMask(GL_TRUE);
__glcheck glClearDepth(double(clear_depth) / max_depth_value);
mask |= GLenum(gl::buffers::depth);
}
@ -875,7 +879,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff;
__glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]);
glClearStencil(clear_stencil);
__glcheck glClearStencil(clear_stencil);
mask |= GLenum(gl::buffers::stencil);
}
@ -926,7 +930,10 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
});
}
glClear(mask);
if (mask)
{
__glcheck glClear(mask);
}
}
using rsx_method_impl_t = void(*)(u32, GLGSRender*);
@ -1179,8 +1186,8 @@ void GLGSRender::init_buffers(bool skip_reading)
u32 clip_y = clip_vertical & 0xffff;
m_surface.unpack(surface_format);
m_surface.width = clip_width + clip_x;
m_surface.height = clip_height + clip_y;
m_surface.width = clip_width * m_surface.width_mult + clip_x;
m_surface.height = clip_height * m_surface.height_mult + clip_y;
rsx::for_each_active_color_surface([&](int index)
{
@ -1188,84 +1195,74 @@ void GLGSRender::init_buffers(bool skip_reading)
u32 location = rsx::method_registers[mr_color_dma[index]];
u32 pitch = rsx::method_registers[mr_color_pitch[index]];
if (pitch <= 64)
{
cached_color_buffers[index] = nullptr;
draw_fbo.color[index] = null_texture;
}
else
{
gl::texture_info info = surface_info(m_surface.color_format, offset, location, m_surface.width, m_surface.height, pitch);
info.antialiasing = m_surface.antialias;
cached_color_buffers[index] = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
draw_fbo.color[index] = cached_color_buffers[index]->view();
}
gl::texture_info info = surface_info(m_surface.color_format, offset, location, m_surface.width, m_surface.height, pitch);
info.antialiasing = m_surface.antialias;
info.swizzled = m_surface.type == CELL_GCM_SURFACE_SWIZZLE;
cached_color_buffers[index] = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
draw_fbo.color[index] = cached_color_buffers[index]->view();
});
if (rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE])
{
u32 offset = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET];
u32 location = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA];
u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z];
if (pitch <= 64)
gl::texture_info info{};
info.width = m_surface.width * m_surface.width_mult;
info.height = m_surface.height * m_surface.height_mult;
info.depth = 1;
info.pitch = pitch;
info.dimension = 2;
info.compressed_size = 0;
info.start_address = rsx::get_address(offset, location);
info.target = gl::texture::target::texture2D;
info.swizzled = false;
switch (m_surface.depth_format)
{
cached_depth_buffer = nullptr;
draw_fbo.depth_stencil = null_texture;
case rsx::surface_depth_format::z16:
info.format.bpp = 2;
info.format.flags = gl::texture_flags::swap_bytes;
info.format.type = gl::texture::type::ushort;
info.format.internal_format = gl::texture::sized_internal_format::depth16;
info.format.format = gl::texture::format::depth;
break;
case rsx::surface_depth_format::z24s8:
info.format.bpp = 4;
info.format.flags = gl::texture_flags::swap_bytes;
info.format.type = gl::texture::type::uint_24_8;
info.format.internal_format = gl::texture::sized_internal_format::depth24_stencil8;
info.format.format = gl::texture::format::depth_stencil;
break;
default:
throw EXCEPTION("");
}
else
info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO };
__glcheck cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
switch (m_surface.depth_format)
{
gl::texture_info info{};
case rsx::surface_depth_format::z16:
__glcheck draw_fbo.depth = cached_depth_buffer->view();
__glcheck draw_fbo.stencil = null_texture;
break;
info.width = m_surface.width;
info.height = m_surface.height;
info.depth = 1;
info.pitch = pitch;
info.dimension = 2;
info.compressed_size = 0;
info.start_address = rsx::get_address(offset, location);
info.target = gl::texture::target::texture2D;
//TODO
info.swizzled = false;
switch (m_surface.depth_format)
{
case rsx::surface_depth_format::z16:
info.format.bpp = 2;
info.format.flags = gl::texture_flags::swap_bytes;
info.format.type = gl::texture::type::ushort;
info.format.internal_format = gl::texture::sized_internal_format::depth16;
info.format.format = gl::texture::format::depth;
break;
case rsx::surface_depth_format::z24s8:
info.format.bpp = 4;
info.format.flags = gl::texture_flags::swap_bytes;
info.format.type = gl::texture::type::uint_24_8;
info.format.internal_format = gl::texture::sized_internal_format::depth24_stencil8;
info.format.format = gl::texture::format::depth_stencil;
break;
default:
throw EXCEPTION("");
}
info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO };
__glcheck 0;
__glcheck cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
switch (m_surface.depth_format)
{
case rsx::surface_depth_format::z16:
__glcheck draw_fbo.depth = cached_depth_buffer->view();
break;
case rsx::surface_depth_format::z24s8:
__glcheck draw_fbo.depth_stencil = cached_depth_buffer->view();
break;
}
case rsx::surface_depth_format::z24s8:
__glcheck draw_fbo.depth_stencil = cached_depth_buffer->view();
break;
}
}
else
{
__glcheck draw_fbo.depth_stencil = null_texture;
cached_depth_buffer = nullptr;
}
__glcheck draw_fbo.bind();
@ -1283,7 +1280,7 @@ void GLGSRender::init_buffers(bool skip_reading)
__glcheck glDrawBuffers(info.second, color_buffers + info.first);
}
set_viewport();
__glcheck set_viewport();
}
void GLGSRender::invalidate_buffers()
@ -1303,6 +1300,7 @@ void GLGSRender::invalidate_buffers()
void GLGSRender::flip(int buffer)
{
//LOG_WARNING(RSX, "flip(%d)", buffer);
u32 buffer_width = gcm_buffers[buffer].width;
u32 buffer_height = gcm_buffers[buffer].height;
u32 buffer_pitch = gcm_buffers[buffer].pitch;
@ -1317,6 +1315,8 @@ void GLGSRender::flip(int buffer)
gl::cached_texture& texture = m_texture_cache.entry(surface_info(rsx::surface_color_format::a8r8g8b8, gcm_buffers[buffer].offset,
CELL_GCM_LOCATION_LOCAL, buffer_width, buffer_height, buffer_pitch), gl::cache_buffers::local);
//std::lock_guard<gl::cached_texture> lock(texture);
m_flip_fbo.bind();
m_flip_fbo.color = texture.view();
m_flip_fbo.draw_buffer(m_flip_fbo.color);
@ -1374,26 +1374,14 @@ bool GLGSRender::on_access_violation(u32 address, bool is_writing)
if (is_writing)
{
const bool accurate_cache = true;
if (accurate_cache)
region->for_each([this](gl::cached_texture& texture)
{
region->for_each([this](gl::cached_texture& texture)
{
invoke([&]()
{
texture.sync(gl::cache_buffers::host);
texture.invalidate(gl::cache_buffers::local);
});
});
}
else
{
region->for_each([](gl::cached_texture& texture)
invoke([&]()
{
texture.sync(gl::cache_buffers::host);
texture.invalidate(gl::cache_buffers::local);
});
}
});
region->unprotect();
}

View file

@ -101,8 +101,6 @@ namespace gl
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_depth.id());
__glcheck 0;
__glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height,
(GLenum)info->format.format, (GLenum)info->format.type, nullptr);
@ -146,31 +144,6 @@ namespace gl
pixels = linear_pixels.get();
}
if (info->antialiasing != rsx::surface_antialiasing::center_1_sample)
{
std::unique_ptr<u8[]> tmp(std::move(linear_pixels));
switch (info->antialiasing)
{
case rsx::surface_antialiasing::square_centered_4_samples:
case rsx::surface_antialiasing::square_rotated_4_samples:
linear_pixels.reset(new u8[info->size() * 4]);
for (u32 y = 0; y < info->height; ++y)
{
for (u32 x = 0; x < info->width; ++x)
{
u32 value = *(u32*)((u8*)pixels + (y * 2 + 0) * info->pitch + (x * 2 + 0) * sizeof(u32));
*(u32*)((u8*)linear_pixels.get() + info->pitch * y + x * sizeof(u32)) = value;
}
}
pixels = linear_pixels.get();
break;
}
}
gl::pixel_unpack_settings{}
.row_length(info->pitch / info->format.bpp)
.aligment(1)
@ -191,6 +164,8 @@ namespace gl
if (info->format.format == gl::texture::format::depth || info->format.format == gl::texture::format::depth_stencil)
{
//LOG_ERROR(RSX, "write depth color to host[0x%x]", info->start_address);
gl::buffer pbo_depth;
pbo_depth.create(info->pitch * info->height);
@ -255,34 +230,7 @@ namespace gl
.swap_bytes((info->format.flags & gl::texture_flags::swap_bytes) != gl::texture_flags::none)
.apply();
if (info->antialiasing == rsx::surface_antialiasing::square_centered_4_samples ||
info->antialiasing == rsx::surface_antialiasing::square_rotated_4_samples)
{
//TODO
std::unique_ptr<u8[]> tmp(new u8[info->size()]);
glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, tmp.get());
u8 *dst = (u8*)vm::base_priv(info->start_address);
for (u32 y = 0; y < info->height; ++y)
{
for (u32 x = 0; x < info->width; ++x)
{
u32 value = *(u32*)((u8*)tmp.get() + info->pitch * y + x * sizeof(u32));
*(u32*)(dst + (y * 2 + 0) * info->pitch + (x * 2 + 0) * sizeof(u32)) = value;
*(u32*)(dst + (y * 2 + 0) * info->pitch + (x * 2 + 1) * sizeof(u32)) = value;
*(u32*)(dst + (y * 2 + 1) * info->pitch + (x * 2 + 0) * sizeof(u32)) = value;
*(u32*)(dst + (y * 2 + 1) * info->pitch + (x * 2 + 1) * sizeof(u32)) = value;
}
}
}
else
{
__glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address));
}
__glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address));
}
ignore(gl::cache_buffers::all);
@ -495,7 +443,7 @@ namespace gl
if (m_current_protection != flags)
{
LOG_WARNING(RSX, "protected region [0x%x, 0x%x)", start_address, start_address + size());
//LOG_WARNING(RSX, "protected region [0x%x, 0x%x)", start_address, start_address + size());
vm::page_protect(start_address, size(), 0, m_current_protection & ~flags, flags);
m_current_protection = flags;
}
@ -521,7 +469,7 @@ namespace gl
}
}
LOG_WARNING(RSX, "unprotected region [0x%x, 0x%x)", start_address, start_address + size());
//LOG_WARNING(RSX, "unprotected region [0x%x, 0x%x)", start_address, start_address + size());
vm::page_protect(start_address, size(), 0, flags, 0);
m_current_protection &= ~flags;
}
@ -682,7 +630,6 @@ namespace gl
}
result->sync(sync);
//region->protect();
return *result;
}

View file

@ -25,10 +25,10 @@ const std::unordered_map<u32, gl::texture_format> textures_fromats
{ CELL_GCM_TEXTURE_B8,{ 1, remap_B8, gl::texture::sized_internal_format::r8, gl::texture::format::red, gl::texture::type::ubyte, gl::texture_flags::none } },
{ CELL_GCM_TEXTURE_A1R5G5B5,{ 2, default_remap, gl::texture::sized_internal_format::rgb5_a1, gl::texture::format::bgra, gl::texture::type::ushort_5_5_5_1, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle } },
{ CELL_GCM_TEXTURE_A4R4G4B4,{ 2, default_remap, gl::texture::sized_internal_format::rgba4, gl::texture::format::bgra, gl::texture::type::ushort_4_4_4_4, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle } },
{ CELL_GCM_TEXTURE_R5G6B5,{ 2, default_remap, gl::texture::sized_internal_format::rgb565, gl::texture::format::bgr, gl::texture::type::ushort_5_6_5, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle } },
{ CELL_GCM_TEXTURE_R5G6B5,{ 2, default_remap, gl::texture::sized_internal_format::rgb565, gl::texture::format::rgb, gl::texture::type::ushort_5_6_5, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle | gl::texture_flags::swap_bytes} },
{ CELL_GCM_TEXTURE_A8R8G8B8,{ 4, default_remap, gl::texture::sized_internal_format::rgba8, gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle } },
{ CELL_GCM_TEXTURE_G8B8,{ 2, remap_G8B8, gl::texture::sized_internal_format::rg8, gl::texture::format::rg, gl::texture::type::ubyte, gl::texture_flags::allow_remap } },
{ CELL_GCM_TEXTURE_R6G5B5,{ 2, remap_R6G5B5, gl::texture::sized_internal_format::rgb565, gl::texture::format::bgr, gl::texture::type::ushort_5_6_5, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle } },
{ CELL_GCM_TEXTURE_R6G5B5,{ 2, remap_R6G5B5, gl::texture::sized_internal_format::rgb565, gl::texture::format::rgb, gl::texture::type::ushort_5_6_5, gl::texture_flags::allow_remap | gl::texture_flags::allow_swizzle | gl::texture_flags::swap_bytes } },
{ CELL_GCM_TEXTURE_DEPTH24_D8,{ 4, default_remap, gl::texture::sized_internal_format::depth24, gl::texture::format::depth, gl::texture::type::uint_8_8_8_8_rev, gl::texture_flags::allow_remap } },
{ CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT,{ 4, default_remap, gl::texture::sized_internal_format::depth24, gl::texture::format::depth, gl::texture::type::f32, gl::texture_flags::allow_remap } },
{ CELL_GCM_TEXTURE_DEPTH16,{ 2, default_remap, gl::texture::sized_internal_format::depth16, gl::texture::format::depth, gl::texture::type::ushort, gl::texture_flags::allow_remap } },
@ -140,8 +140,20 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
{
u32 full_format = tex.format();
u32 format = full_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
bool is_swizzled = (~full_format & CELL_GCM_TEXTURE_LN) != 0;
bool is_normalized = (~full_format & CELL_GCM_TEXTURE_UN) != 0;
bool is_compressed = compressed_format(format);
bool is_swizzled;
bool is_normalized;
if (is_compressed)
{
is_swizzled = false;
is_normalized = true;
}
else
{
is_swizzled = (~full_format & CELL_GCM_TEXTURE_LN) != 0;
is_normalized = (~full_format & CELL_GCM_TEXTURE_UN) != 0;
}
gl::texture::target target = is_normalized ? gl::texture::target::texture2D : gl::texture::target::texture_rectangle;
@ -153,8 +165,6 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
return;
}
bool is_compressed = compressed_format(full_format);
const GLint *remap = default_remap.data();
//TODO
@ -165,8 +175,8 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
info.depth = std::max<u16>(tex.depth(), 1);
info.dimension = tex.dimension();
info.start_address = rsx::get_address(tex.offset(), tex.location());
info.target = target;
info.swizzled = is_swizzled;
info.target = target;
if (is_compressed)
{
@ -209,12 +219,7 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
}
info.format = found->second;
info.pitch = tex.pitch();
if (!info.pitch)
{
info.pitch = info.width * info.format.bpp;
}
info.pitch = std::max(info.width * info.format.bpp, tex.pitch());
remap = info.format.remap.data();
}
@ -222,7 +227,6 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
__glcheck cache.entry(info, gl::cache_buffers::local).bind(tex.index());
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
__glcheck glTexParameteri((GLenum)target, GL_GENERATE_MIPMAP, tex.mipmap() > 1);
if ((info.format.flags & gl::texture_flags::allow_remap) != gl::texture_flags::none)
{
@ -231,33 +235,40 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
u8 remap_g = (tex.remap() >> 4) & 0x3;
u8 remap_b = (tex.remap() >> 6) & 0x3;
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_A, remap[remap_a]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_R, remap[remap_r]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_G, remap[remap_g]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_B, remap[remap_b]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_A, remap[remap_a]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_R, remap[remap_r]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_G, remap[remap_g]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_B, remap[remap_b]);
}
else
{
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_A, remap[0]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_R, remap[1]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_G, remap[2]);
glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_B, remap[3]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_A, remap[0]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_R, remap[1]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_G, remap[2]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_SWIZZLE_B, remap[3]);
}
glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_S, wrap(tex.wrap_s()));
glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_T, wrap(tex.wrap_t()));
glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_R, wrap(tex.wrap_r()));
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_S, wrap(tex.wrap_s()));
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_T, wrap(tex.wrap_t()));
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_WRAP_R, wrap(tex.wrap_r()));
glTexParameteri((GLenum)target, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (GLint)tex.bias());
glTexParameteri((GLenum)target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
__glcheck glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (GLint)tex.bias());
glTexParameteri((GLenum)target, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
glTexParameteri((GLenum)target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
glTexParameterf((GLenum)target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
__glcheck glTexParameterf((GLenum)target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
__glcheck 0;
if (target != gl::texture::target::texture_rectangle)
{
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
__glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
if (tex.mipmap() > 1)
{
__glcheck glGenerateMipmap((GLenum)target);
}
}
}

View file

@ -561,7 +561,8 @@ namespace rsx
else
{
++m_internal_task_waiters;
while (add_internal_task(callback).wait_for(1s) == std::future_status::timeout)
auto future = add_internal_task(callback);
while (future.wait_for(1s) == std::future_status::timeout)
{
CHECK_EMU_STATUS;
}

View file

@ -163,12 +163,15 @@ namespace rsx
{
u8 log2height;
u8 log2width;
u8 type;
surface_antialiasing antialias;
surface_depth_format depth_format;
surface_color_format color_format;
u32 width;
u32 height;
u8 width_mult;
u8 height_mult;
u32 format;
void unpack(u32 surface_format)
@ -178,9 +181,29 @@ namespace rsx
log2height = surface_format >> 24;
log2width = (surface_format >> 16) & 0xff;
antialias = to_surface_antialiasing((surface_format >> 12) & 0xf);
type = (surface_format >> 8) & 0xf;
depth_format = to_surface_depth_format((surface_format >> 5) & 0x7);
color_format = to_surface_color_format(surface_format & 0x1f);
switch (antialias)
{
case surface_antialiasing::center_1_sample:
width_mult = 1;
height_mult = 1;
break;
case surface_antialiasing::diagonal_centered_2_samples:
width_mult = 2;
height_mult = 1;
break;
case surface_antialiasing::square_rotated_4_samples:
case surface_antialiasing::square_centered_4_samples:
width_mult = 2;
height_mult = 2;
break;
}
width = 1 << (u32(log2width) + 1);
height = 1 << (u32(log2width) + 1);
}