Merge branch 'rgb565' of https://github.com/Themaister/RetroArch
This commit is contained in:
commit
b6ed2cac67
|
@ -8,7 +8,7 @@ HAVE_LOGGER = 0
|
||||||
HAVE_FILE_LOGGER = 0
|
HAVE_FILE_LOGGER = 0
|
||||||
PERF_TEST = 0
|
PERF_TEST = 0
|
||||||
|
|
||||||
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
|
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.100"
|
||||||
PC_DEVELOPMENT_UDP_PORT = 3490
|
PC_DEVELOPMENT_UDP_PORT = 3490
|
||||||
|
|
||||||
# system platform
|
# system platform
|
||||||
|
|
|
@ -199,6 +199,14 @@ DRIVERS
|
||||||
============================================================ */
|
============================================================ */
|
||||||
#include "../../driver.c"
|
#include "../../driver.c"
|
||||||
|
|
||||||
|
/*============================================================
|
||||||
|
SCALERS
|
||||||
|
============================================================ */
|
||||||
|
#include "../../gfx/scaler/filter.c"
|
||||||
|
#include "../../gfx/scaler/pixconv.c"
|
||||||
|
#include "../../gfx/scaler/scaler.c"
|
||||||
|
#include "../../gfx/scaler/scaler_int.c"
|
||||||
|
|
||||||
/*============================================================
|
/*============================================================
|
||||||
FIFO BUFFER
|
FIFO BUFFER
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
logger_send("RetroArch Salamander: " __VA_ARGS__); \
|
logger_send("RetroArch Salamander: " __VA_ARGS__); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define RARCH_LOG_OUTPUT(...) do { \
|
||||||
|
logger_send("RetroArch Salamander [OUTPUT] :: " __VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define RARCH_ERR(...) do { \
|
#define RARCH_ERR(...) do { \
|
||||||
logger_send("RetroArch Salamander [ERROR] :: " __VA_ARGS__); \
|
logger_send("RetroArch Salamander [ERROR] :: " __VA_ARGS__); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
@ -48,6 +52,10 @@
|
||||||
logger_send("RetroArch [WARN] :: " __VA_ARGS__); \
|
logger_send("RetroArch [WARN] :: " __VA_ARGS__); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define RARCH_LOG_OUTPUT(...) do { \
|
||||||
|
logger_send("RetroArch [OUTPUT] :: " __VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(HAVE_FILE_LOGGER)
|
#elif defined(HAVE_FILE_LOGGER)
|
||||||
|
@ -76,6 +84,13 @@ extern FILE * log_fp;
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef RARCH_LOG_OUTPUT
|
||||||
|
#define RARCH_LOG_OUTPUT(...) do { \
|
||||||
|
fprintf(log_fp, "RetroArch Salamander [OUTPUT] :: " __VA_ARGS__); \
|
||||||
|
fflush(log_fp); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifndef RARCH_LOG
|
#ifndef RARCH_LOG
|
||||||
|
@ -99,6 +114,13 @@ extern FILE * log_fp;
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef RARCH_LOG_OUTPUT
|
||||||
|
#define RARCH_LOG_OUTPUT(...) do { \
|
||||||
|
fprintf(log_fp, "RetroArch [OUTPUT] :: " __VA_ARGS__); \
|
||||||
|
fflush(log_fp); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
90
driver.c
90
driver.c
|
@ -423,19 +423,32 @@ void uninit_audio(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DYLIB
|
#ifdef HAVE_DYLIB
|
||||||
static void init_filter(void)
|
static void deinit_filter(void)
|
||||||
|
{
|
||||||
|
g_extern.filter.active = false;
|
||||||
|
|
||||||
|
if (g_extern.filter.lib)
|
||||||
|
dylib_close(g_extern.filter.lib);
|
||||||
|
g_extern.filter.lib = NULL;
|
||||||
|
|
||||||
|
free(g_extern.filter.buffer);
|
||||||
|
free(g_extern.filter.colormap);
|
||||||
|
free(g_extern.filter.scaler_out);
|
||||||
|
g_extern.filter.buffer = NULL;
|
||||||
|
g_extern.filter.colormap = NULL;
|
||||||
|
g_extern.filter.scaler_out = NULL;
|
||||||
|
|
||||||
|
scaler_ctx_gen_reset(&g_extern.filter.scaler);
|
||||||
|
memset(&g_extern.filter.scaler, 0, sizeof(g_extern.filter.scaler));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_filter(bool rgb32)
|
||||||
{
|
{
|
||||||
if (g_extern.filter.active)
|
if (g_extern.filter.active)
|
||||||
return;
|
return;
|
||||||
if (*g_settings.video.filter_path == '\0')
|
if (!*g_settings.video.filter_path)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_extern.system.pix_fmt != RETRO_PIXEL_FORMAT_0RGB1555)
|
|
||||||
{
|
|
||||||
RARCH_WARN("CPU filters only support 0RGB1555.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RARCH_LOG("Loading bSNES filter from \"%s\"\n", g_settings.video.filter_path);
|
RARCH_LOG("Loading bSNES filter from \"%s\"\n", g_settings.video.filter_path);
|
||||||
g_extern.filter.lib = dylib_load(g_settings.video.filter_path);
|
g_extern.filter.lib = dylib_load(g_settings.video.filter_path);
|
||||||
if (!g_extern.filter.lib)
|
if (!g_extern.filter.lib)
|
||||||
|
@ -444,6 +457,13 @@ static void init_filter(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
|
||||||
|
unsigned width = geom->max_width;
|
||||||
|
unsigned height = geom->max_height;
|
||||||
|
unsigned pow2_x = 0;
|
||||||
|
unsigned pow2_y = 0;
|
||||||
|
unsigned maxsize = 0;
|
||||||
|
|
||||||
g_extern.filter.psize =
|
g_extern.filter.psize =
|
||||||
(void (*)(unsigned*, unsigned*))dylib_proc(g_extern.filter.lib, "filter_size");
|
(void (*)(unsigned*, unsigned*))dylib_proc(g_extern.filter.lib, "filter_size");
|
||||||
g_extern.filter.prender =
|
g_extern.filter.prender =
|
||||||
|
@ -454,31 +474,27 @@ static void init_filter(void)
|
||||||
if (!g_extern.filter.psize || !g_extern.filter.prender)
|
if (!g_extern.filter.psize || !g_extern.filter.prender)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to find functions in filter...\n");
|
RARCH_ERR("Failed to find functions in filter...\n");
|
||||||
dylib_close(g_extern.filter.lib);
|
goto error;
|
||||||
g_extern.filter.lib = NULL;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_extern.filter.active = true;
|
g_extern.filter.active = true;
|
||||||
|
|
||||||
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
|
|
||||||
unsigned width = geom->max_width;
|
|
||||||
unsigned height = geom->max_height;
|
|
||||||
g_extern.filter.psize(&width, &height);
|
g_extern.filter.psize(&width, &height);
|
||||||
|
|
||||||
unsigned pow2_x = next_pow2(width);
|
pow2_x = next_pow2(width);
|
||||||
unsigned pow2_y = next_pow2(height);
|
pow2_y = next_pow2(height);
|
||||||
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
|
maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
|
||||||
g_extern.filter.scale = maxsize / RARCH_SCALE_BASE;
|
g_extern.filter.scale = maxsize / RARCH_SCALE_BASE;
|
||||||
|
|
||||||
g_extern.filter.buffer = (uint32_t*)malloc(RARCH_SCALE_BASE * RARCH_SCALE_BASE *
|
g_extern.filter.buffer = (uint32_t*)malloc(RARCH_SCALE_BASE * RARCH_SCALE_BASE *
|
||||||
g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
||||||
rarch_assert(g_extern.filter.buffer);
|
if (!g_extern.filter.buffer)
|
||||||
|
goto error;
|
||||||
|
|
||||||
g_extern.filter.pitch = RARCH_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
|
g_extern.filter.pitch = RARCH_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
|
||||||
|
|
||||||
g_extern.filter.colormap = (uint32_t*)malloc(0x10000 * sizeof(uint32_t));
|
g_extern.filter.colormap = (uint32_t*)malloc(0x10000 * sizeof(uint32_t));
|
||||||
rarch_assert(g_extern.filter.colormap);
|
if (!g_extern.filter.colormap)
|
||||||
|
goto error;
|
||||||
|
|
||||||
// Set up conversion map from 16-bit XRGB1555 to 32-bit ARGB.
|
// Set up conversion map from 16-bit XRGB1555 to 32-bit ARGB.
|
||||||
for (unsigned i = 0; i < 0x10000; i++)
|
for (unsigned i = 0; i < 0x10000; i++)
|
||||||
|
@ -492,18 +508,23 @@ static void init_filter(void)
|
||||||
b = (b << 3) | (b >> 2);
|
b = (b << 3) | (b >> 2);
|
||||||
g_extern.filter.colormap[i] = (r << 16) | (g << 8) | (b << 0);
|
g_extern.filter.colormap[i] = (r << 16) | (g << 8) | (b << 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void deinit_filter(void)
|
g_extern.filter.scaler_out = (uint16_t*)malloc(sizeof(uint16_t) * geom->max_width * geom->max_height);
|
||||||
{
|
if (!g_extern.filter.scaler_out)
|
||||||
if (!g_extern.filter.active)
|
goto error;
|
||||||
return;
|
|
||||||
|
|
||||||
g_extern.filter.active = false;
|
g_extern.filter.scaler.scaler_type = SCALER_TYPE_POINT;
|
||||||
dylib_close(g_extern.filter.lib);
|
g_extern.filter.scaler.in_fmt = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
|
||||||
g_extern.filter.lib = NULL;
|
g_extern.filter.scaler.out_fmt = SCALER_FMT_0RGB1555;
|
||||||
free(g_extern.filter.buffer);
|
|
||||||
free(g_extern.filter.colormap);
|
if (!scaler_ctx_gen_filter(&g_extern.filter.scaler))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
RARCH_ERR("CPU filter init failed.\n");
|
||||||
|
deinit_filter();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -542,13 +563,6 @@ static bool init_video_pixel_converter(unsigned size)
|
||||||
{
|
{
|
||||||
RARCH_WARN("0RGB1555 pixel format is deprecated, and will be slower. For 15/16-bit, RGB565 format is preferred.\n");
|
RARCH_WARN("0RGB1555 pixel format is deprecated, and will be slower. For 15/16-bit, RGB565 format is preferred.\n");
|
||||||
|
|
||||||
// We'll tweak these values later,
|
|
||||||
// just set most of them to something sane to begin with.
|
|
||||||
driver.scaler.in_width =
|
|
||||||
driver.scaler.in_height =
|
|
||||||
driver.scaler.out_width =
|
|
||||||
driver.scaler.out_height = size;
|
|
||||||
|
|
||||||
driver.scaler.scaler_type = SCALER_TYPE_POINT;
|
driver.scaler.scaler_type = SCALER_TYPE_POINT;
|
||||||
driver.scaler.in_fmt = SCALER_FMT_0RGB1555;
|
driver.scaler.in_fmt = SCALER_FMT_0RGB1555;
|
||||||
|
|
||||||
|
@ -567,7 +581,7 @@ static bool init_video_pixel_converter(unsigned size)
|
||||||
void init_video_input(void)
|
void init_video_input(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DYLIB
|
#ifdef HAVE_DYLIB
|
||||||
init_filter();
|
init_filter(g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_XML
|
#ifdef HAVE_XML
|
||||||
|
|
|
@ -355,6 +355,10 @@ struct global
|
||||||
void (*psize)(unsigned *width, unsigned *height);
|
void (*psize)(unsigned *width, unsigned *height);
|
||||||
void (*prender)(uint32_t *colormap, uint32_t *output, unsigned outpitch,
|
void (*prender)(uint32_t *colormap, uint32_t *output, unsigned outpitch,
|
||||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height);
|
const uint16_t *input, unsigned pitch, unsigned width, unsigned height);
|
||||||
|
|
||||||
|
// CPU filters only work on *XRGB1555*. We have to convert to XRGB1555 first.
|
||||||
|
struct scaler_ctx scaler;
|
||||||
|
uint16_t *scaler_out;
|
||||||
} filter;
|
} filter;
|
||||||
|
|
||||||
msg_queue_t *msg_queue;
|
msg_queue_t *msg_queue;
|
||||||
|
|
|
@ -237,6 +237,8 @@ static bool gfx_ctx_set_video_mode(
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigaction(SIGINT, &sa, NULL);
|
sigaction(SIGINT, &sa, NULL);
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
|
int x_off = 0;
|
||||||
|
int y_off = 0;
|
||||||
|
|
||||||
bool windowed_full = g_settings.video.windowed_fullscreen;
|
bool windowed_full = g_settings.video.windowed_fullscreen;
|
||||||
bool true_full = false;
|
bool true_full = false;
|
||||||
|
@ -264,8 +266,6 @@ static bool gfx_ctx_set_video_mode(
|
||||||
if (g_settings.video.monitor_index)
|
if (g_settings.video.monitor_index)
|
||||||
g_screen = g_settings.video.monitor_index - 1;
|
g_screen = g_settings.video.monitor_index - 1;
|
||||||
|
|
||||||
int x_off = 0;
|
|
||||||
int y_off = 0;
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
if (fullscreen || g_screen != 0)
|
if (fullscreen || g_screen != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -199,13 +199,13 @@ static XineramaScreenInfo *x11_query_screens(Display *dpy, int *num_screens)
|
||||||
{
|
{
|
||||||
int major, minor;
|
int major, minor;
|
||||||
if (!XineramaQueryExtension(dpy, &major, &minor))
|
if (!XineramaQueryExtension(dpy, &major, &minor))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
XineramaQueryVersion(dpy, &major, &minor);
|
XineramaQueryVersion(dpy, &major, &minor);
|
||||||
RARCH_LOG("[X11]: Xinerama version: %d.%d.\n", major, minor);
|
RARCH_LOG("[X11]: Xinerama version: %d.%d.\n", major, minor);
|
||||||
|
|
||||||
if (!XineramaIsActive(dpy))
|
if (!XineramaIsActive(dpy))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
return XineramaQueryScreens(dpy, num_screens);
|
return XineramaQueryScreens(dpy, num_screens);
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,8 @@ static bool gfx_ctx_set_video_mode(
|
||||||
XVisualInfo *vi = NULL;
|
XVisualInfo *vi = NULL;
|
||||||
bool windowed_full = g_settings.video.windowed_fullscreen;
|
bool windowed_full = g_settings.video.windowed_fullscreen;
|
||||||
bool true_full = false;
|
bool true_full = false;
|
||||||
|
int x_off = 0;
|
||||||
|
int y_off = 0;
|
||||||
|
|
||||||
EGLint vid;
|
EGLint vid;
|
||||||
if (!eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &vid))
|
if (!eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &vid))
|
||||||
|
@ -292,8 +294,6 @@ static bool gfx_ctx_set_video_mode(
|
||||||
if (g_settings.video.monitor_index)
|
if (g_settings.video.monitor_index)
|
||||||
g_screen = g_settings.video.monitor_index - 1;
|
g_screen = g_settings.video.monitor_index - 1;
|
||||||
|
|
||||||
int x_off = 0;
|
|
||||||
int y_off = 0;
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
if (fullscreen || g_screen != 0)
|
if (fullscreen || g_screen != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,61 @@
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSE2_)
|
||||||
|
void conv_rgb565_0rgb1555(void *output_, const void *input_,
|
||||||
|
int width, int height,
|
||||||
|
int out_stride, int in_stride)
|
||||||
|
{
|
||||||
|
const uint16_t *input = (const uint16_t*)input_;
|
||||||
|
uint16_t *output = (uint16_t*)output_;
|
||||||
|
|
||||||
|
int max_width = width - 7;
|
||||||
|
|
||||||
|
const __m128i hi_mask = _mm_set1_epi16(0x7fe0);
|
||||||
|
const __m128i lo_mask = _mm_set1_epi16(0x1f);
|
||||||
|
|
||||||
|
for (int h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
for (w = 0; w < max_width; w += 8)
|
||||||
|
{
|
||||||
|
const __m128i in = _mm_loadu_si128((const __m128i*)(input + w));
|
||||||
|
__m128i hi = _mm_and_si128(_mm_slli_epi16(in, 1), hi_mask);
|
||||||
|
__m128i lo = _mm_and_si128(in, lo_mask);
|
||||||
|
_mm_storeu_si128((__m128i*)(output + w), _mm_or_si128(hi, lo));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; w < width; w++)
|
||||||
|
{
|
||||||
|
uint16_t col = input[w];
|
||||||
|
uint16_t hi = (col >> 1) & 0x7fe0;
|
||||||
|
uint16_t lo = col & 0x1f;
|
||||||
|
output[w] = hi | lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void conv_rgb565_0rgb1555(void *output_, const void *input_,
|
||||||
|
int width, int height,
|
||||||
|
int out_stride, int in_stride)
|
||||||
|
{
|
||||||
|
const uint16_t *input = (const uint16_t*)input_;
|
||||||
|
uint16_t *output = (uint16_t*)output_;
|
||||||
|
|
||||||
|
for (int h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
|
||||||
|
{
|
||||||
|
for (int w = 0; w < width; w++)
|
||||||
|
{
|
||||||
|
uint16_t col = input[w];
|
||||||
|
uint16_t hi = (col >> 1) & 0x7fe0;
|
||||||
|
uint16_t lo = col & 0x1f;
|
||||||
|
output[w] = hi | lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__SSE2__)
|
#if defined(__SSE2__)
|
||||||
void conv_0rgb1555_rgb565(void *output_, const void *input_,
|
void conv_0rgb1555_rgb565(void *output_, const void *input_,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
|
|
|
@ -24,6 +24,10 @@ void conv_0rgb1555_rgb565(void *output, const void *input,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int out_stride, int in_stride);
|
int out_stride, int in_stride);
|
||||||
|
|
||||||
|
void conv_rgb565_0rgb1555(void *output, const void *input,
|
||||||
|
int width, int height,
|
||||||
|
int out_stride, int in_stride);
|
||||||
|
|
||||||
void conv_rgb565_argb8888(void *output, const void *input,
|
void conv_rgb565_argb8888(void *output, const void *input,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int out_stride, int in_stride);
|
int out_stride, int in_stride);
|
||||||
|
|
|
@ -74,6 +74,8 @@ static bool set_direct_pix_conv(struct scaler_ctx *ctx)
|
||||||
ctx->direct_pixconv = conv_rgb565_bgr24;
|
ctx->direct_pixconv = conv_rgb565_bgr24;
|
||||||
else if (ctx->in_fmt == SCALER_FMT_0RGB1555 && ctx->out_fmt == SCALER_FMT_RGB565)
|
else if (ctx->in_fmt == SCALER_FMT_0RGB1555 && ctx->out_fmt == SCALER_FMT_RGB565)
|
||||||
ctx->direct_pixconv = conv_0rgb1555_rgb565;
|
ctx->direct_pixconv = conv_0rgb1555_rgb565;
|
||||||
|
else if (ctx->in_fmt == SCALER_FMT_RGB565 && ctx->out_fmt == SCALER_FMT_0RGB1555)
|
||||||
|
ctx->direct_pixconv = conv_rgb565_0rgb1555;
|
||||||
else if (ctx->in_fmt == SCALER_FMT_BGR24 && ctx->out_fmt == SCALER_FMT_ARGB8888)
|
else if (ctx->in_fmt == SCALER_FMT_BGR24 && ctx->out_fmt == SCALER_FMT_ARGB8888)
|
||||||
ctx->direct_pixconv = conv_bgr24_argb8888;
|
ctx->direct_pixconv = conv_bgr24_argb8888;
|
||||||
else if (ctx->in_fmt == SCALER_FMT_ARGB8888 && ctx->out_fmt == SCALER_FMT_0RGB1555)
|
else if (ctx->in_fmt == SCALER_FMT_ARGB8888 && ctx->out_fmt == SCALER_FMT_0RGB1555)
|
||||||
|
|
|
@ -135,12 +135,6 @@ void gx_set_video_mode(unsigned fbWidth, unsigned lines)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lines == 0 || fbWidth == 0)
|
|
||||||
{
|
|
||||||
VIDEO_GetPreferredMode(&gx_mode);
|
|
||||||
goto config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines <= max_height / 2)
|
if (lines <= max_height / 2)
|
||||||
{
|
{
|
||||||
modetype = VI_NON_INTERLACE;
|
modetype = VI_NON_INTERLACE;
|
||||||
|
@ -151,6 +145,12 @@ void gx_set_video_mode(unsigned fbWidth, unsigned lines)
|
||||||
modetype = (progressive) ? VI_PROGRESSIVE : VI_INTERLACE;
|
modetype = (progressive) ? VI_PROGRESSIVE : VI_INTERLACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lines == 0 || fbWidth == 0)
|
||||||
|
{
|
||||||
|
VIDEO_GetPreferredMode(&gx_mode);
|
||||||
|
goto config;
|
||||||
|
}
|
||||||
|
|
||||||
if (lines > max_height)
|
if (lines > max_height)
|
||||||
lines = max_height;
|
lines = max_height;
|
||||||
if (fbWidth > max_width)
|
if (fbWidth > max_width)
|
||||||
|
@ -236,6 +236,7 @@ config:
|
||||||
GX_SetFieldMode(gx_mode.field_rendering, (gx_mode.viHeight == 2 * gx_mode.xfbHeight) ? GX_ENABLE : GX_DISABLE);
|
GX_SetFieldMode(gx_mode.field_rendering, (gx_mode.viHeight == 2 * gx_mode.xfbHeight) ? GX_ENABLE : GX_DISABLE);
|
||||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||||
GX_InvalidateTexAll();
|
GX_InvalidateTexAll();
|
||||||
|
GX_Flush();
|
||||||
|
|
||||||
g_current_framebuf = 0;
|
g_current_framebuf = 0;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +281,7 @@ static void init_texture(unsigned width, unsigned height)
|
||||||
{
|
{
|
||||||
unsigned g_filter = g_settings.video.smooth ? GX_LINEAR : GX_NEAR;
|
unsigned g_filter = g_settings.video.smooth ? GX_LINEAR : GX_NEAR;
|
||||||
|
|
||||||
GX_InitTexObj(&g_tex.obj, g_tex.data, width, height, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
GX_InitTexObj(&g_tex.obj, g_tex.data, width, height, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
GX_InitTexObjLOD(&g_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1);
|
GX_InitTexObjLOD(&g_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1);
|
||||||
GX_InitTexObj(&menu_tex.obj, menu_tex.data, RGUI_WIDTH, RGUI_HEIGHT, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
GX_InitTexObj(&menu_tex.obj, menu_tex.data, RGUI_WIDTH, RGUI_HEIGHT, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
GX_InitTexObjLOD(&menu_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1);
|
GX_InitTexObjLOD(&menu_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1);
|
||||||
|
@ -439,7 +440,7 @@ static void gx_start(void)
|
||||||
#ifdef ASM_BLITTER
|
#ifdef ASM_BLITTER
|
||||||
|
|
||||||
static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, const uint32_t *dst,
|
static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, const uint32_t *dst,
|
||||||
unsigned width, unsigned height, unsigned pitch, unsigned ormask)
|
unsigned width, unsigned height, unsigned pitch)
|
||||||
{
|
{
|
||||||
register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b, line3, line3b, line4, line4b, line5;
|
register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b, line3, line3b, line4, line4b, line5;
|
||||||
|
|
||||||
|
@ -461,31 +462,23 @@ static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, c
|
||||||
" mr %[tmp0], %[src] \n"
|
" mr %[tmp0], %[src] \n"
|
||||||
|
|
||||||
"1: lwz %[tmp1], 0(%[src]) \n"
|
"1: lwz %[tmp1], 0(%[src]) \n"
|
||||||
" or %[tmp1], %[tmp1], %[ormask] \n"
|
|
||||||
" stwu %[tmp1], 8(%[dst]) \n"
|
" stwu %[tmp1], 8(%[dst]) \n"
|
||||||
" lwz %[tmp2], 4(%[src]) \n"
|
" lwz %[tmp2], 4(%[src]) \n"
|
||||||
" or %[tmp2], %[tmp2], %[ormask] \n"
|
|
||||||
" stwu %[tmp2], 8(%[tmp3]) \n"
|
" stwu %[tmp2], 8(%[tmp3]) \n"
|
||||||
|
|
||||||
" lwzx %[tmp1], %[line2], %[src] \n"
|
" lwzx %[tmp1], %[line2], %[src] \n"
|
||||||
" or %[tmp1], %[tmp1], %[ormask] \n"
|
|
||||||
" stwu %[tmp1], 8(%[dst]) \n"
|
" stwu %[tmp1], 8(%[dst]) \n"
|
||||||
" lwzx %[tmp2], %[line2b], %[src] \n"
|
" lwzx %[tmp2], %[line2b], %[src] \n"
|
||||||
" or %[tmp2], %[tmp2], %[ormask] \n"
|
|
||||||
" stwu %[tmp2], 8(%[tmp3]) \n"
|
" stwu %[tmp2], 8(%[tmp3]) \n"
|
||||||
|
|
||||||
" lwzx %[tmp1], %[line3], %[src] \n"
|
" lwzx %[tmp1], %[line3], %[src] \n"
|
||||||
" or %[tmp1], %[tmp1], %[ormask] \n"
|
|
||||||
" stwu %[tmp1], 8(%[dst]) \n"
|
" stwu %[tmp1], 8(%[dst]) \n"
|
||||||
" lwzx %[tmp2], %[line3b], %[src] \n"
|
" lwzx %[tmp2], %[line3b], %[src] \n"
|
||||||
" or %[tmp2], %[tmp2], %[ormask] \n"
|
|
||||||
" stwu %[tmp2], 8(%[tmp3]) \n"
|
" stwu %[tmp2], 8(%[tmp3]) \n"
|
||||||
|
|
||||||
" lwzx %[tmp1], %[line4], %[src] \n"
|
" lwzx %[tmp1], %[line4], %[src] \n"
|
||||||
" or %[tmp1], %[tmp1], %[ormask] \n"
|
|
||||||
" stwu %[tmp1], 8(%[dst]) \n"
|
" stwu %[tmp1], 8(%[dst]) \n"
|
||||||
" lwzx %[tmp2], %[line4b], %[src] \n"
|
" lwzx %[tmp2], %[line4b], %[src] \n"
|
||||||
" or %[tmp2], %[tmp2], %[ormask] \n"
|
|
||||||
" stwu %[tmp2], 8(%[tmp3]) \n"
|
" stwu %[tmp2], 8(%[tmp3]) \n"
|
||||||
|
|
||||||
" addi %[src], %[src], 8 \n"
|
" addi %[src], %[src], 8 \n"
|
||||||
|
@ -509,8 +502,7 @@ static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, c
|
||||||
: [src] "b" (src),
|
: [src] "b" (src),
|
||||||
[width] "b" (width),
|
[width] "b" (width),
|
||||||
[height] "b" (height),
|
[height] "b" (height),
|
||||||
[pitch] "b" (pitch),
|
[pitch] "b" (pitch)
|
||||||
[ormask] "b" (ormask)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,14 +514,14 @@ static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, c
|
||||||
uint32_t *tmp_dst = dst; \
|
uint32_t *tmp_dst = dst; \
|
||||||
for (unsigned x = 0; x < width2; x += 8, tmp_src += 8, tmp_dst += 32) \
|
for (unsigned x = 0; x < width2; x += 8, tmp_src += 8, tmp_dst += 32) \
|
||||||
{ \
|
{ \
|
||||||
tmp_dst[ 0 + off] = RGB15toRGB5A3(tmp_src[0]); \
|
tmp_dst[ 0 + off] = tmp_src[0]; \
|
||||||
tmp_dst[ 1 + off] = RGB15toRGB5A3(tmp_src[1]); \
|
tmp_dst[ 1 + off] = tmp_src[1]; \
|
||||||
tmp_dst[ 8 + off] = RGB15toRGB5A3(tmp_src[2]); \
|
tmp_dst[ 8 + off] = tmp_src[2]; \
|
||||||
tmp_dst[ 9 + off] = RGB15toRGB5A3(tmp_src[3]); \
|
tmp_dst[ 9 + off] = tmp_src[3]; \
|
||||||
tmp_dst[16 + off] = RGB15toRGB5A3(tmp_src[4]); \
|
tmp_dst[16 + off] = tmp_src[4]; \
|
||||||
tmp_dst[17 + off] = RGB15toRGB5A3(tmp_src[5]); \
|
tmp_dst[17 + off] = tmp_src[5]; \
|
||||||
tmp_dst[24 + off] = RGB15toRGB5A3(tmp_src[6]); \
|
tmp_dst[24 + off] = tmp_src[6]; \
|
||||||
tmp_dst[25 + off] = RGB15toRGB5A3(tmp_src[7]); \
|
tmp_dst[25 + off] = tmp_src[7]; \
|
||||||
} \
|
} \
|
||||||
src2 += tmp_pitch; \
|
src2 += tmp_pitch; \
|
||||||
}
|
}
|
||||||
|
@ -543,7 +535,7 @@ static void update_texture(const uint32_t *src,
|
||||||
#ifdef ASM_BLITTER
|
#ifdef ASM_BLITTER
|
||||||
if (width && height && !(width & 3) && !(height & 3))
|
if (width && height && !(width & 3) && !(height & 3))
|
||||||
{
|
{
|
||||||
update_texture_asm(src, g_tex.data, width, height, pitch, 0x80008000U);
|
update_texture_asm(src, g_tex.data, width, height, pitch);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -559,13 +551,10 @@ static void update_texture(const uint32_t *src,
|
||||||
uint32_t *dst = g_tex.data;
|
uint32_t *dst = g_tex.data;
|
||||||
for (unsigned i = 0; i < height; i += 4, dst += 4 * width2)
|
for (unsigned i = 0; i < height; i += 4, dst += 4 * width2)
|
||||||
{
|
{
|
||||||
// Set MSB to get full RGB555.
|
|
||||||
#define RGB15toRGB5A3(col) ((col) | 0x80008000u)
|
|
||||||
BLIT_LINE(0)
|
BLIT_LINE(0)
|
||||||
BLIT_LINE(2)
|
BLIT_LINE(2)
|
||||||
BLIT_LINE(4)
|
BLIT_LINE(4)
|
||||||
BLIT_LINE(6)
|
BLIT_LINE(6)
|
||||||
#undef RGB15toRGB5A3
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,7 +562,7 @@ static void update_texture(const uint32_t *src,
|
||||||
if(gx->menu_render)
|
if(gx->menu_render)
|
||||||
{
|
{
|
||||||
#ifdef ASM_BLITTER
|
#ifdef ASM_BLITTER
|
||||||
update_texture_asm(gx->menu_data, menu_tex.data, RGUI_WIDTH, RGUI_HEIGHT, RGUI_WIDTH * 2, 0x00000000U);
|
update_texture_asm(gx->menu_data, menu_tex.data, RGUI_WIDTH, RGUI_HEIGHT, RGUI_WIDTH * 2);
|
||||||
#else
|
#else
|
||||||
unsigned tmp_pitch = (RGUI_WIDTH * 2) >> 2;
|
unsigned tmp_pitch = (RGUI_WIDTH * 2) >> 2;
|
||||||
unsigned width2 = RGUI_WIDTH >> 1;
|
unsigned width2 = RGUI_WIDTH >> 1;
|
||||||
|
@ -582,12 +571,10 @@ static void update_texture(const uint32_t *src,
|
||||||
uint32_t *dst = menu_tex.data;
|
uint32_t *dst = menu_tex.data;
|
||||||
for (unsigned i = 0; i < RGUI_HEIGHT; i += 4, dst += 4 * width2)
|
for (unsigned i = 0; i < RGUI_HEIGHT; i += 4, dst += 4 * width2)
|
||||||
{
|
{
|
||||||
#define RGB15toRGB5A3(col) (col)
|
|
||||||
BLIT_LINE(0)
|
BLIT_LINE(0)
|
||||||
BLIT_LINE(2)
|
BLIT_LINE(2)
|
||||||
BLIT_LINE(4)
|
BLIT_LINE(4)
|
||||||
BLIT_LINE(6)
|
BLIT_LINE(6)
|
||||||
#undef RGB15toRGB5A3
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
10
retroarch.c
10
retroarch.c
|
@ -283,11 +283,19 @@ static void video_frame(const void *data, unsigned width, unsigned height, size_
|
||||||
#ifdef HAVE_DYLIB
|
#ifdef HAVE_DYLIB
|
||||||
if (g_extern.filter.active && data)
|
if (g_extern.filter.active && data)
|
||||||
{
|
{
|
||||||
|
struct scaler_ctx *scaler = &g_extern.filter.scaler;
|
||||||
|
scaler->in_width = scaler->out_width = width;
|
||||||
|
scaler->in_height = scaler->out_height = height;
|
||||||
|
scaler->in_stride = pitch;
|
||||||
|
scaler->out_stride = width * sizeof(uint16_t);
|
||||||
|
|
||||||
|
scaler_ctx_scale(scaler, g_extern.filter.scaler_out, data);
|
||||||
|
|
||||||
unsigned owidth = width;
|
unsigned owidth = width;
|
||||||
unsigned oheight = height;
|
unsigned oheight = height;
|
||||||
g_extern.filter.psize(&owidth, &oheight);
|
g_extern.filter.psize(&owidth, &oheight);
|
||||||
g_extern.filter.prender(g_extern.filter.colormap, g_extern.filter.buffer,
|
g_extern.filter.prender(g_extern.filter.colormap, g_extern.filter.buffer,
|
||||||
g_extern.filter.pitch, (const uint16_t*)data, pitch, width, height);
|
g_extern.filter.pitch, g_extern.filter.scaler_out, scaler->out_stride, width, height);
|
||||||
|
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef HAVE_FFMPEG
|
||||||
if (g_extern.recording && g_settings.video.post_filter_record)
|
if (g_extern.recording && g_settings.video.post_filter_record)
|
||||||
|
|
Loading…
Reference in New Issue