mirror of https://github.com/xemu-project/xemu.git
add support for some signed texture formats
This commit is contained in:
parent
57cdee770e
commit
195324558e
|
@ -222,7 +222,7 @@ static const ColorFormatInfo kelvin_color_format_gl_map[66] = {
|
||||||
{GL_RED, GL_RED, GL_RED, GL_GREEN}},
|
{GL_RED, GL_RED, GL_RED, GL_GREEN}},
|
||||||
|
|
||||||
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
|
||||||
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE}, /* FIXME: This might be signed */
|
{2, false, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE},
|
||||||
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
|
||||||
{2, false, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
|
{2, false, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
|
||||||
{GL_RED, GL_GREEN, GL_RED, GL_GREEN}},
|
{GL_RED, GL_GREEN, GL_RED, GL_GREEN}},
|
||||||
|
@ -276,6 +276,17 @@ static const ColorFormatInfo kelvin_color_format_gl_map[66] = {
|
||||||
{4, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
|
{4, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const ColorFormatInfo kelvin_signed_color_format_gl_map[66] = {
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
|
||||||
|
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE},
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
|
||||||
|
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE,
|
||||||
|
{GL_RED, GL_GREEN, GL_RED, GL_GREEN}},
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] =
|
||||||
|
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE,
|
||||||
|
{GL_GREEN, GL_RED, GL_RED, GL_GREEN}},
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct SurfaceFormatInfo {
|
typedef struct SurfaceFormatInfo {
|
||||||
unsigned int bytes_per_pixel;
|
unsigned int bytes_per_pixel;
|
||||||
GLint gl_internal_format;
|
GLint gl_internal_format;
|
||||||
|
@ -319,4 +330,12 @@ static const SurfaceFormatInfo kelvin_surface_zeta_fixed_format_gl_map[] = {
|
||||||
{4, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT},
|
{4, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint32_t kelvin_signed_format_mask_gl_map[66] = {
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
|
||||||
|
NV_PGRAPH_TEXFILTER0_RSIGNED | NV_PGRAPH_TEXFILTER0_GSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED,
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
|
||||||
|
NV_PGRAPH_TEXFILTER0_GSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED,
|
||||||
|
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] =
|
||||||
|
NV_PGRAPH_TEXFILTER0_RSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include "gloffscreen.h"
|
#include "gloffscreen.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct SurfaceBinding {
|
typedef struct SurfaceBinding {
|
||||||
QTAILQ_ENTRY(SurfaceBinding) entry;
|
QTAILQ_ENTRY(SurfaceBinding) entry;
|
||||||
|
@ -271,7 +272,7 @@ void pgraph_gl_init_buffers(NV2AState *d);
|
||||||
void pgraph_gl_finalize_buffers(PGRAPHState *pg);
|
void pgraph_gl_finalize_buffers(PGRAPHState *pg);
|
||||||
void pgraph_gl_process_pending_downloads(NV2AState *d);
|
void pgraph_gl_process_pending_downloads(NV2AState *d);
|
||||||
void pgraph_gl_reload_surface_scale_factor(PGRAPHState *pg);
|
void pgraph_gl_reload_surface_scale_factor(PGRAPHState *pg);
|
||||||
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface, TextureBinding *texture, TextureShape *texture_shape, int texture_unit);
|
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface, TextureBinding *texture, TextureShape *texture_shape, int texture_unit, uint32_t filter);
|
||||||
void pgraph_gl_set_surface_dirty(PGRAPHState *pg, bool color, bool zeta);
|
void pgraph_gl_set_surface_dirty(PGRAPHState *pg, bool color, bool zeta);
|
||||||
void pgraph_gl_surface_download_if_dirty(NV2AState *d, SurfaceBinding *surface);
|
void pgraph_gl_surface_download_if_dirty(NV2AState *d, SurfaceBinding *surface);
|
||||||
SurfaceBinding *pgraph_gl_surface_get(NV2AState *d, hwaddr addr);
|
SurfaceBinding *pgraph_gl_surface_get(NV2AState *d, hwaddr addr);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "hw/xbox/nv2a/pgraph/swizzle.h"
|
#include "hw/xbox/nv2a/pgraph/swizzle.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static void surface_download(NV2AState *d, SurfaceBinding *surface, bool force);
|
static void surface_download(NV2AState *d, SurfaceBinding *surface, bool force);
|
||||||
static void surface_download_to_buffer(NV2AState *d, SurfaceBinding *surface,
|
static void surface_download_to_buffer(NV2AState *d, SurfaceBinding *surface,
|
||||||
|
@ -280,11 +281,16 @@ static void render_surface_to_texture_slow(NV2AState *d,
|
||||||
SurfaceBinding *surface,
|
SurfaceBinding *surface,
|
||||||
TextureBinding *texture,
|
TextureBinding *texture,
|
||||||
TextureShape *texture_shape,
|
TextureShape *texture_shape,
|
||||||
int texture_unit)
|
int texture_unit,
|
||||||
|
uint32_t filter)
|
||||||
{
|
{
|
||||||
PGRAPHState *pg = &d->pgraph;
|
PGRAPHState *pg = &d->pgraph;
|
||||||
|
|
||||||
const ColorFormatInfo *f = &kelvin_color_format_gl_map[texture_shape->color_format];
|
ColorFormatInfo f = kelvin_color_format_gl_map[texture_shape->color_format];
|
||||||
|
uint32_t mask = kelvin_signed_format_mask_gl_map[texture_shape->color_format];
|
||||||
|
if (mask && (filter & mask) == mask)
|
||||||
|
f = kelvin_signed_color_format_gl_map[texture_shape->color_format];
|
||||||
|
|
||||||
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
|
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
|
||||||
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX_FALLBACK);
|
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX_FALLBACK);
|
||||||
|
|
||||||
|
@ -304,8 +310,8 @@ static void render_surface_to_texture_slow(NV2AState *d,
|
||||||
height = texture_shape->height;
|
height = texture_shape->height;
|
||||||
pgraph_apply_scaling_factor(pg, &width, &height);
|
pgraph_apply_scaling_factor(pg, &width, &height);
|
||||||
|
|
||||||
glTexImage2D(texture->gl_target, 0, f->gl_internal_format, width, height, 0,
|
glTexImage2D(texture->gl_target, 0, f.gl_internal_format, width, height, 0,
|
||||||
f->gl_format, f->gl_type, buf);
|
f.gl_format, f.gl_type, buf);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
glBindTexture(texture->gl_target, texture->gl_texture);
|
glBindTexture(texture->gl_target, texture->gl_texture);
|
||||||
}
|
}
|
||||||
|
@ -317,20 +323,23 @@ static void render_surface_to_texture_slow(NV2AState *d,
|
||||||
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface,
|
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface,
|
||||||
TextureBinding *texture,
|
TextureBinding *texture,
|
||||||
TextureShape *texture_shape,
|
TextureShape *texture_shape,
|
||||||
int texture_unit)
|
int texture_unit,
|
||||||
|
uint32_t filter)
|
||||||
{
|
{
|
||||||
PGRAPHState *pg = &d->pgraph;
|
PGRAPHState *pg = &d->pgraph;
|
||||||
PGRAPHGLState *r = pg->gl_renderer_state;
|
PGRAPHGLState *r = pg->gl_renderer_state;
|
||||||
|
|
||||||
const ColorFormatInfo *f =
|
ColorFormatInfo f = kelvin_color_format_gl_map[texture_shape->color_format];
|
||||||
&kelvin_color_format_gl_map[texture_shape->color_format];
|
uint32_t mask = kelvin_signed_format_mask_gl_map[texture_shape->color_format];
|
||||||
|
if (mask && (filter & mask) == mask)
|
||||||
|
f = kelvin_signed_color_format_gl_map[texture_shape->color_format];
|
||||||
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
|
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
|
||||||
|
|
||||||
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX);
|
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX);
|
||||||
|
|
||||||
if (!surface_to_texture_can_fastpath(surface, texture_shape)) {
|
if (!surface_to_texture_can_fastpath(surface, texture_shape)) {
|
||||||
render_surface_to_texture_slow(d, surface, texture,
|
render_surface_to_texture_slow(d, surface, texture,
|
||||||
texture_shape, texture_unit);
|
texture_shape, texture_unit, filter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +351,8 @@ void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface,
|
||||||
glTexParameteri(texture->gl_target, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(texture->gl_target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(texture->gl_target, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(texture->gl_target, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
glTexParameteri(texture->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(texture->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexImage2D(texture->gl_target, 0, f->gl_internal_format, width, height, 0,
|
glTexImage2D(texture->gl_target, 0, f.gl_internal_format, width, height, 0,
|
||||||
f->gl_format, f->gl_type, NULL);
|
f.gl_format, f.gl_type, NULL);
|
||||||
glBindTexture(texture->gl_target, 0);
|
glBindTexture(texture->gl_target, 0);
|
||||||
render_surface_to(d, surface, texture_unit, texture->gl_target,
|
render_surface_to(d, surface, texture_unit, texture->gl_target,
|
||||||
texture->gl_texture, width, height);
|
texture->gl_texture, width, height);
|
||||||
|
|
|
@ -24,10 +24,12 @@
|
||||||
#include "hw/xbox/nv2a/pgraph/swizzle.h"
|
#include "hw/xbox/nv2a/pgraph/swizzle.h"
|
||||||
#include "hw/xbox/nv2a/pgraph/s3tc.h"
|
#include "hw/xbox/nv2a/pgraph/s3tc.h"
|
||||||
#include "hw/xbox/nv2a/pgraph/texture.h"
|
#include "hw/xbox/nv2a/pgraph/texture.h"
|
||||||
|
#include "constants.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data);
|
static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data, uint32_t filter);
|
||||||
static void texture_binding_destroy(gpointer data);
|
static void texture_binding_destroy(gpointer data);
|
||||||
|
|
||||||
struct pgraph_texture_possibly_dirty_struct {
|
struct pgraph_texture_possibly_dirty_struct {
|
||||||
|
@ -343,7 +345,7 @@ void pgraph_gl_bind_textures(NV2AState *d)
|
||||||
|
|
||||||
if (key_out->binding == NULL) {
|
if (key_out->binding == NULL) {
|
||||||
// Must create the texture
|
// Must create the texture
|
||||||
key_out->binding = generate_texture(state, texture_data, palette_data);
|
key_out->binding = generate_texture(state, texture_data, palette_data, filter);
|
||||||
key_out->binding->data_hash = tex_data_hash;
|
key_out->binding->data_hash = tex_data_hash;
|
||||||
key_out->binding->scale = 1;
|
key_out->binding->scale = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -360,7 +362,7 @@ void pgraph_gl_bind_textures(NV2AState *d)
|
||||||
|
|
||||||
trace_nv2a_pgraph_surface_render_to_texture(
|
trace_nv2a_pgraph_surface_render_to_texture(
|
||||||
surface->vram_addr, surface->width, surface->height);
|
surface->vram_addr, surface->width, surface->height);
|
||||||
pgraph_gl_render_surface_to_texture(d, surface, binding, &state, i);
|
pgraph_gl_render_surface_to_texture(d, surface, binding, &state, i, filter);
|
||||||
binding->draw_time = surface->draw_time;
|
binding->draw_time = surface->draw_time;
|
||||||
binding->scale = pg->surface_scale_factor;
|
binding->scale = pg->surface_scale_factor;
|
||||||
}
|
}
|
||||||
|
@ -403,9 +405,14 @@ gl_internal_format_to_s3tc_enum(GLint gl_internal_format)
|
||||||
static void upload_gl_texture(GLenum gl_target,
|
static void upload_gl_texture(GLenum gl_target,
|
||||||
const TextureShape s,
|
const TextureShape s,
|
||||||
const uint8_t *texture_data,
|
const uint8_t *texture_data,
|
||||||
const uint8_t *palette_data)
|
const uint8_t *palette_data,
|
||||||
|
uint32_t filter)
|
||||||
{
|
{
|
||||||
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
|
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
|
||||||
|
uint32_t mask = kelvin_signed_format_mask_gl_map[s.color_format];
|
||||||
|
if (mask && (filter & mask) == mask)
|
||||||
|
f = kelvin_signed_color_format_gl_map[s.color_format];
|
||||||
|
|
||||||
nv2a_profile_inc_counter(NV2A_PROF_TEX_UPLOAD);
|
nv2a_profile_inc_counter(NV2A_PROF_TEX_UPLOAD);
|
||||||
|
|
||||||
unsigned int adjusted_width = s.width;
|
unsigned int adjusted_width = s.width;
|
||||||
|
@ -620,9 +627,13 @@ static void upload_gl_texture(GLenum gl_target,
|
||||||
|
|
||||||
static TextureBinding* generate_texture(const TextureShape s,
|
static TextureBinding* generate_texture(const TextureShape s,
|
||||||
const uint8_t *texture_data,
|
const uint8_t *texture_data,
|
||||||
const uint8_t *palette_data)
|
const uint8_t *palette_data,
|
||||||
|
uint32_t filter)
|
||||||
{
|
{
|
||||||
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
|
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
|
||||||
|
uint32_t mask = kelvin_signed_format_mask_gl_map[s.color_format];
|
||||||
|
if (mask && (filter & mask) == mask)
|
||||||
|
f = kelvin_signed_color_format_gl_map[s.color_format];
|
||||||
|
|
||||||
/* Create a new opengl texture */
|
/* Create a new opengl texture */
|
||||||
GLuint gl_texture;
|
GLuint gl_texture;
|
||||||
|
@ -690,19 +701,19 @@ static TextureBinding* generate_texture(const TextureShape s,
|
||||||
length = (length + NV2A_CUBEMAP_FACE_ALIGNMENT - 1) & ~(NV2A_CUBEMAP_FACE_ALIGNMENT - 1);
|
length = (length + NV2A_CUBEMAP_FACE_ALIGNMENT - 1) & ~(NV2A_CUBEMAP_FACE_ALIGNMENT - 1);
|
||||||
|
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||||
s, texture_data + 0 * length, palette_data);
|
s, texture_data + 0 * length, palette_data, filter);
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||||
s, texture_data + 1 * length, palette_data);
|
s, texture_data + 1 * length, palette_data, filter);
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||||
s, texture_data + 2 * length, palette_data);
|
s, texture_data + 2 * length, palette_data, filter);
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||||
s, texture_data + 3 * length, palette_data);
|
s, texture_data + 3 * length, palette_data, filter);
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||||
s, texture_data + 4 * length, palette_data);
|
s, texture_data + 4 * length, palette_data, filter);
|
||||||
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
||||||
s, texture_data + 5 * length, palette_data);
|
s, texture_data + 5 * length, palette_data, filter);
|
||||||
} else {
|
} else {
|
||||||
upload_gl_texture(gl_target, s, texture_data, palette_data);
|
upload_gl_texture(gl_target, s, texture_data, palette_data, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linear textures don't support mipmapping */
|
/* Linear textures don't support mipmapping */
|
||||||
|
|
Loading…
Reference in New Issue