Skip to content

Commit bf12abf

Browse files
committed
add support for some signed texture formats
1 parent 86344a8 commit bf12abf

File tree

4 files changed

+60
-24
lines changed

4 files changed

+60
-24
lines changed

hw/xbox/nv2a/pgraph/gl/constants.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ static const ColorFormatInfo kelvin_color_format_gl_map[66] = {
222222
{GL_RED, GL_RED, GL_RED, GL_GREEN}},
223223

224224
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
225-
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE}, /* FIXME: This might be signed */
225+
{2, false, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE},
226226
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
227227
{2, false, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
228228
{GL_RED, GL_GREEN, GL_RED, GL_GREEN}},
@@ -276,6 +276,17 @@ static const ColorFormatInfo kelvin_color_format_gl_map[66] = {
276276
{4, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
277277
};
278278

279+
static const ColorFormatInfo kelvin_signed_color_format_gl_map[66] = {
280+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
281+
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE},
282+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
283+
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE,
284+
{GL_RED, GL_GREEN, GL_RED, GL_GREEN}},
285+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] =
286+
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE,
287+
{GL_GREEN, GL_RED, GL_RED, GL_GREEN}},
288+
};
289+
279290
typedef struct SurfaceFormatInfo {
280291
unsigned int bytes_per_pixel;
281292
GLint gl_internal_format;
@@ -319,4 +330,12 @@ static const SurfaceFormatInfo kelvin_surface_zeta_fixed_format_gl_map[] = {
319330
{4, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT},
320331
};
321332

333+
static const uint32_t kelvin_signed_format_mask_gl_map[66] = {
334+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] =
335+
NV_PGRAPH_TEXFILTER0_RSIGNED | NV_PGRAPH_TEXFILTER0_GSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED,
336+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
337+
NV_PGRAPH_TEXFILTER0_GSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED,
338+
[NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] =
339+
NV_PGRAPH_TEXFILTER0_RSIGNED | NV_PGRAPH_TEXFILTER0_BSIGNED
340+
};
322341
#endif

hw/xbox/nv2a/pgraph/gl/renderer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "gloffscreen.h"
3939
#include "constants.h"
40+
#include <stdint.h>
4041

4142
typedef struct SurfaceBinding {
4243
QTAILQ_ENTRY(SurfaceBinding) entry;
@@ -270,7 +271,7 @@ void pgraph_gl_init_buffers(NV2AState *d);
270271
void pgraph_gl_finalize_buffers(PGRAPHState *pg);
271272
void pgraph_gl_process_pending_downloads(NV2AState *d);
272273
void pgraph_gl_reload_surface_scale_factor(PGRAPHState *pg);
273-
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface, TextureBinding *texture, TextureShape *texture_shape, int texture_unit);
274+
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface, TextureBinding *texture, TextureShape *texture_shape, int texture_unit, uint32_t filter);
274275
void pgraph_gl_set_surface_dirty(PGRAPHState *pg, bool color, bool zeta);
275276
void pgraph_gl_surface_download_if_dirty(NV2AState *d, SurfaceBinding *surface);
276277
SurfaceBinding *pgraph_gl_surface_get(NV2AState *d, hwaddr addr);

hw/xbox/nv2a/pgraph/gl/surface.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "hw/xbox/nv2a/pgraph/swizzle.h"
2626
#include "debug.h"
2727
#include "renderer.h"
28+
#include <stdint.h>
2829

2930
static void surface_download(NV2AState *d, SurfaceBinding *surface, bool force);
3031
static void surface_download_to_buffer(NV2AState *d, SurfaceBinding *surface,
@@ -280,11 +281,15 @@ static void render_surface_to_texture_slow(NV2AState *d,
280281
SurfaceBinding *surface,
281282
TextureBinding *texture,
282283
TextureShape *texture_shape,
283-
int texture_unit)
284+
int texture_unit,
285+
uint32_t filter)
284286
{
285287
PGRAPHState *pg = &d->pgraph;
286288

287-
const ColorFormatInfo *f = &kelvin_color_format_gl_map[texture_shape->color_format];
289+
ColorFormatInfo f = kelvin_color_format_gl_map[texture_shape->color_format];
290+
if (filter & kelvin_signed_format_mask_gl_map[texture_shape->color_format])
291+
f = kelvin_signed_color_format_gl_map[texture_shape->color_format];
292+
288293
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
289294
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX_FALLBACK);
290295

@@ -304,8 +309,8 @@ static void render_surface_to_texture_slow(NV2AState *d,
304309
height = texture_shape->height;
305310
pgraph_apply_scaling_factor(pg, &width, &height);
306311

307-
glTexImage2D(texture->gl_target, 0, f->gl_internal_format, width, height, 0,
308-
f->gl_format, f->gl_type, buf);
312+
glTexImage2D(texture->gl_target, 0, f.gl_internal_format, width, height, 0,
313+
f.gl_format, f.gl_type, buf);
309314
g_free(buf);
310315
glBindTexture(texture->gl_target, texture->gl_texture);
311316
}
@@ -317,20 +322,22 @@ static void render_surface_to_texture_slow(NV2AState *d,
317322
void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface,
318323
TextureBinding *texture,
319324
TextureShape *texture_shape,
320-
int texture_unit)
325+
int texture_unit,
326+
uint32_t filter)
321327
{
322328
PGRAPHState *pg = &d->pgraph;
323329
PGRAPHGLState *r = pg->gl_renderer_state;
324330

325-
const ColorFormatInfo *f =
326-
&kelvin_color_format_gl_map[texture_shape->color_format];
331+
ColorFormatInfo f = kelvin_color_format_gl_map[texture_shape->color_format];
332+
if (filter & kelvin_signed_format_mask_gl_map[texture_shape->color_format])
333+
f = kelvin_signed_color_format_gl_map[texture_shape->color_format];
327334
assert(texture_shape->color_format < ARRAY_SIZE(kelvin_color_format_gl_map));
328335

329336
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX);
330337

331338
if (!surface_to_texture_can_fastpath(surface, texture_shape)) {
332339
render_surface_to_texture_slow(d, surface, texture,
333-
texture_shape, texture_unit);
340+
texture_shape, texture_unit, filter);
334341
return;
335342
}
336343

@@ -342,8 +349,8 @@ void pgraph_gl_render_surface_to_texture(NV2AState *d, SurfaceBinding *surface,
342349
glTexParameteri(texture->gl_target, GL_TEXTURE_BASE_LEVEL, 0);
343350
glTexParameteri(texture->gl_target, GL_TEXTURE_MAX_LEVEL, 0);
344351
glTexParameteri(texture->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
345-
glTexImage2D(texture->gl_target, 0, f->gl_internal_format, width, height, 0,
346-
f->gl_format, f->gl_type, NULL);
352+
glTexImage2D(texture->gl_target, 0, f.gl_internal_format, width, height, 0,
353+
f.gl_format, f.gl_type, NULL);
347354
glBindTexture(texture->gl_target, 0);
348355
render_surface_to(d, surface, texture_unit, texture->gl_target,
349356
texture->gl_texture, width, height);

hw/xbox/nv2a/pgraph/gl/texture.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
#include "hw/xbox/nv2a/pgraph/swizzle.h"
2525
#include "hw/xbox/nv2a/pgraph/s3tc.h"
2626
#include "hw/xbox/nv2a/pgraph/texture.h"
27+
#include "constants.h"
2728
#include "debug.h"
2829
#include "renderer.h"
30+
#include <stdint.h>
2931

30-
static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data);
32+
static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data, uint32_t filter);
3133
static void texture_binding_destroy(gpointer data);
3234

3335
struct pgraph_texture_possibly_dirty_struct {
@@ -343,7 +345,7 @@ void pgraph_gl_bind_textures(NV2AState *d)
343345

344346
if (key_out->binding == NULL) {
345347
// Must create the texture
346-
key_out->binding = generate_texture(state, texture_data, palette_data);
348+
key_out->binding = generate_texture(state, texture_data, palette_data, filter);
347349
key_out->binding->data_hash = tex_data_hash;
348350
key_out->binding->scale = 1;
349351
} else {
@@ -360,7 +362,7 @@ void pgraph_gl_bind_textures(NV2AState *d)
360362

361363
trace_nv2a_pgraph_surface_render_to_texture(
362364
surface->vram_addr, surface->width, surface->height);
363-
pgraph_gl_render_surface_to_texture(d, surface, binding, &state, i);
365+
pgraph_gl_render_surface_to_texture(d, surface, binding, &state, i, filter);
364366
binding->draw_time = surface->draw_time;
365367
binding->scale = pg->surface_scale_factor;
366368
}
@@ -403,9 +405,13 @@ gl_internal_format_to_s3tc_enum(GLint gl_internal_format)
403405
static void upload_gl_texture(GLenum gl_target,
404406
const TextureShape s,
405407
const uint8_t *texture_data,
406-
const uint8_t *palette_data)
408+
const uint8_t *palette_data,
409+
uint32_t filter)
407410
{
408411
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
412+
if (filter & kelvin_signed_format_mask_gl_map[s.color_format])
413+
f = kelvin_signed_color_format_gl_map[s.color_format];
414+
409415
nv2a_profile_inc_counter(NV2A_PROF_TEX_UPLOAD);
410416

411417
unsigned int adjusted_width = s.width;
@@ -626,9 +632,12 @@ static void upload_gl_texture(GLenum gl_target,
626632

627633
static TextureBinding* generate_texture(const TextureShape s,
628634
const uint8_t *texture_data,
629-
const uint8_t *palette_data)
635+
const uint8_t *palette_data,
636+
uint32_t filter)
630637
{
631638
ColorFormatInfo f = kelvin_color_format_gl_map[s.color_format];
639+
if (filter & kelvin_signed_format_mask_gl_map[s.color_format])
640+
f = kelvin_signed_color_format_gl_map[s.color_format];
632641

633642
/* Create a new opengl texture */
634643
GLuint gl_texture;
@@ -696,19 +705,19 @@ static TextureBinding* generate_texture(const TextureShape s,
696705
length = (length + NV2A_CUBEMAP_FACE_ALIGNMENT - 1) & ~(NV2A_CUBEMAP_FACE_ALIGNMENT - 1);
697706

698707
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
699-
s, texture_data + 0 * length, palette_data);
708+
s, texture_data + 0 * length, palette_data, filter);
700709
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
701-
s, texture_data + 1 * length, palette_data);
710+
s, texture_data + 1 * length, palette_data, filter);
702711
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
703-
s, texture_data + 2 * length, palette_data);
712+
s, texture_data + 2 * length, palette_data, filter);
704713
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
705-
s, texture_data + 3 * length, palette_data);
714+
s, texture_data + 3 * length, palette_data, filter);
706715
upload_gl_texture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
707-
s, texture_data + 4 * length, palette_data);
716+
s, texture_data + 4 * length, palette_data, filter);
708717
upload_gl_texture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
709-
s, texture_data + 5 * length, palette_data);
718+
s, texture_data + 5 * length, palette_data, filter);
710719
} else {
711-
upload_gl_texture(gl_target, s, texture_data, palette_data);
720+
upload_gl_texture(gl_target, s, texture_data, palette_data, filter);
712721
}
713722

714723
/* Linear textures don't support mipmapping */

0 commit comments

Comments
 (0)