|
|
|
@ -32,6 +32,8 @@
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "gfx/common/gx2_common.h"
|
|
|
|
|
#include "gfx/video_shader_parse.h"
|
|
|
|
|
#include "gfx/drivers_shader/slang_preprocess.h"
|
|
|
|
|
#include "system/memory.h"
|
|
|
|
|
|
|
|
|
|
#include "wiiu_dbg.h"
|
|
|
|
@ -51,7 +53,8 @@ static const wiiu_render_mode_t wiiu_render_mode_map[] =
|
|
|
|
|
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P} /* GX2_TV_SCAN_MODE_1080P */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void wiiu_set_tex_coords(frame_vertex_t* v, GX2Texture* texture, float u0, float v0, float u1, float v1, unsigned rotation)
|
|
|
|
|
static void wiiu_set_tex_coords(frame_vertex_t *v, GX2Texture *texture, float u0, float v0, float u1, float v1,
|
|
|
|
|
unsigned rotation)
|
|
|
|
|
{
|
|
|
|
|
v[0].coord.u = u0 / texture->surface.width;
|
|
|
|
|
v[0].coord.v = v0 / texture->surface.height;
|
|
|
|
@ -98,6 +101,7 @@ static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu)
|
|
|
|
|
float desired_aspect = video_driver_get_aspect_ratio();
|
|
|
|
|
|
|
|
|
|
#if defined(HAVE_MENU)
|
|
|
|
|
|
|
|
|
|
if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
|
|
|
|
{
|
|
|
|
|
const struct video_viewport *custom = video_viewport_get_custom();
|
|
|
|
@ -220,6 +224,7 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
|
|
|
|
|
|
|
|
|
/* setup scanbuffers */
|
|
|
|
|
wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()];
|
|
|
|
|
// wiiu->render_mode = wiiu_render_mode_map[GX2_TV_SCAN_MODE_480P];
|
|
|
|
|
GX2CalcTVSize(wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
|
|
|
|
|
GX2_BUFFERING_MODE_DOUBLE, &size, &tmp);
|
|
|
|
|
|
|
|
|
@ -267,7 +272,8 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
|
|
|
|
GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
|
|
|
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
|
|
|
|
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
|
|
|
|
|
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
|
|
|
|
|
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
|
|
|
|
GX2_BLEND_COMBINE_MODE_ADD,
|
|
|
|
|
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
|
|
|
|
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE);
|
|
|
|
|
|
|
|
|
@ -293,35 +299,6 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
|
|
|
|
wiiu->input_ring_buffer = MEM1_alloc(wiiu->input_ring_buffer_size, 0x1000);
|
|
|
|
|
wiiu->output_ring_buffer = MEM1_alloc(wiiu->output_ring_buffer_size, 0x1000);
|
|
|
|
|
|
|
|
|
|
/* Initialize frame texture */
|
|
|
|
|
memset(&wiiu->texture, 0, sizeof(GX2Texture));
|
|
|
|
|
wiiu->texture.surface.width = video->input_scale * RARCH_SCALE_BASE;
|
|
|
|
|
wiiu->texture.surface.height = video->input_scale * RARCH_SCALE_BASE;
|
|
|
|
|
wiiu->texture.surface.depth = 1;
|
|
|
|
|
wiiu->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
|
|
|
|
wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
|
|
|
|
wiiu->texture.viewNumSlices = 1;
|
|
|
|
|
wiiu->rgb32 = video->rgb32;
|
|
|
|
|
|
|
|
|
|
if(wiiu->rgb32)
|
|
|
|
|
{
|
|
|
|
|
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
|
|
|
|
wiiu->texture.compMap = GX2_COMP_SEL(_G, _B, _A, _1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
|
|
|
|
|
wiiu->texture.compMap = GX2_COMP_SEL(_B, _G, _R, _1);
|
|
|
|
|
}
|
|
|
|
|
GX2CalcSurfaceSizeAndAlignment(&wiiu->texture.surface);
|
|
|
|
|
GX2InitTextureRegs(&wiiu->texture);
|
|
|
|
|
|
|
|
|
|
wiiu->texture.surface.image = MEM2_alloc(wiiu->texture.surface.imageSize,
|
|
|
|
|
wiiu->texture.surface.alignment);
|
|
|
|
|
memset(wiiu->texture.surface.image, 0x0, wiiu->texture.surface.imageSize);
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
|
|
|
|
|
wiiu->texture.surface.imageSize);
|
|
|
|
|
|
|
|
|
|
/* init menu texture */
|
|
|
|
|
memset(&wiiu->menu.texture, 0, sizeof(GX2Texture));
|
|
|
|
|
wiiu->menu.texture.surface.width = 512;
|
|
|
|
@ -463,6 +440,7 @@ static void gx2_overlay_vertex_geom(void *data, unsigned image,
|
|
|
|
|
static void gx2_free_overlay(wiiu_video_t *gx2)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gx2->overlays; i++)
|
|
|
|
|
MEM2_free(gx2->overlay[i].tex.surface.image);
|
|
|
|
|
|
|
|
|
@ -481,6 +459,7 @@ static bool gx2_overlay_load(void *data,
|
|
|
|
|
|
|
|
|
|
gx2_free_overlay(gx2);
|
|
|
|
|
gx2->overlay = (struct gx2_overlay_data *)calloc(num_images, sizeof(*gx2->overlay));
|
|
|
|
|
|
|
|
|
|
if (!gx2->overlay)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
@ -557,7 +536,8 @@ static void gx2_render_overlay(void *data)
|
|
|
|
|
|
|
|
|
|
wiiu_video_t *gx2 = (wiiu_video_t *)data;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gx2->overlays; i++){
|
|
|
|
|
for (i = 0; i < gx2->overlays; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
GX2SetAttribBuffer(0, sizeof(gx2->overlay[i].v), sizeof(gx2->overlay[i].v), &gx2->overlay[i].v);
|
|
|
|
|
|
|
|
|
@ -570,7 +550,8 @@ static void gx2_render_overlay(void *data)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const video_overlay_interface_t gx2_overlay_interface = {
|
|
|
|
|
static const video_overlay_interface_t gx2_overlay_interface =
|
|
|
|
|
{
|
|
|
|
|
gx2_overlay_enable,
|
|
|
|
|
gx2_overlay_load,
|
|
|
|
|
gx2_overlay_tex_geom,
|
|
|
|
@ -587,6 +568,25 @@ static void gx2_get_overlay_interface(void *data,
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void wiiu_free_shader_preset(wiiu_video_t *wiiu)
|
|
|
|
|
{
|
|
|
|
|
if (!wiiu->shader_preset)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
{
|
|
|
|
|
gfd_free(wiiu->pass[i].gfd);
|
|
|
|
|
MEM2_free(wiiu->pass[i].vs_ubo);
|
|
|
|
|
MEM2_free(wiiu->pass[i].ps_ubo);
|
|
|
|
|
MEM1_free(wiiu->pass[i].texture.surface.image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(wiiu->pass, 0, sizeof(wiiu->pass));
|
|
|
|
|
|
|
|
|
|
free(wiiu->shader_preset);
|
|
|
|
|
wiiu->shader_preset = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void wiiu_gfx_free(void *data)
|
|
|
|
|
{
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *) data;
|
|
|
|
@ -594,9 +594,6 @@ static void wiiu_gfx_free(void* data)
|
|
|
|
|
if (!wiiu)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_OVERLAY
|
|
|
|
|
gx2_free_overlay(wiiu);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* clear leftover image */
|
|
|
|
|
GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
@ -614,6 +611,11 @@ static void wiiu_gfx_free(void* data)
|
|
|
|
|
|
|
|
|
|
GX2DestroyShader(&frame_shader);
|
|
|
|
|
GX2DestroyShader(&sprite_shader);
|
|
|
|
|
wiiu_free_shader_preset(wiiu);
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_OVERLAY
|
|
|
|
|
gx2_free_overlay(wiiu);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
MEM2_free(wiiu->ctx_state);
|
|
|
|
|
MEM2_free(wiiu->cmd_buffer);
|
|
|
|
@ -636,6 +638,139 @@ static void wiiu_gfx_free(void* data)
|
|
|
|
|
free(wiiu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigned height)
|
|
|
|
|
{
|
|
|
|
|
MEM2_free(wiiu->texture.surface.image);
|
|
|
|
|
if(wiiu->shader_preset)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
MEM1_free(wiiu->pass[i].texture.surface.image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize frame texture */
|
|
|
|
|
memset(&wiiu->texture, 0, sizeof(GX2Texture));
|
|
|
|
|
wiiu->texture.surface.width = width;
|
|
|
|
|
wiiu->texture.surface.height = height;
|
|
|
|
|
wiiu->texture.surface.depth = 1;
|
|
|
|
|
wiiu->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
|
|
|
|
wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
|
|
|
|
wiiu->texture.viewNumSlices = 1;
|
|
|
|
|
wiiu->rgb32 = wiiu->rgb32;
|
|
|
|
|
|
|
|
|
|
if (wiiu->rgb32)
|
|
|
|
|
{
|
|
|
|
|
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
|
|
|
|
wiiu->texture.compMap = GX2_COMP_SEL(_G, _B, _A, _1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
|
|
|
|
|
wiiu->texture.compMap = GX2_COMP_SEL(_B, _G, _R, _1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GX2CalcSurfaceSizeAndAlignment(&wiiu->texture.surface);
|
|
|
|
|
GX2InitTextureRegs(&wiiu->texture);
|
|
|
|
|
|
|
|
|
|
wiiu->texture.surface.image = MEM2_alloc(wiiu->texture.surface.imageSize,
|
|
|
|
|
wiiu->texture.surface.alignment);
|
|
|
|
|
memset(wiiu->texture.surface.image, 0x0, wiiu->texture.surface.imageSize);
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
|
|
|
|
|
wiiu->texture.surface.imageSize);
|
|
|
|
|
|
|
|
|
|
if(wiiu->shader_preset)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
{
|
|
|
|
|
struct video_shader_pass *pass = &wiiu->shader_preset->pass[i];
|
|
|
|
|
|
|
|
|
|
switch (pass->fbo.type_x)
|
|
|
|
|
{
|
|
|
|
|
case RARCH_SCALE_INPUT:
|
|
|
|
|
width *= pass->fbo.scale_x;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RARCH_SCALE_VIEWPORT:
|
|
|
|
|
width = wiiu->vp.width * pass->fbo.scale_x;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RARCH_SCALE_ABSOLUTE:
|
|
|
|
|
width = pass->fbo.abs_x;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (pass->fbo.type_y)
|
|
|
|
|
{
|
|
|
|
|
case RARCH_SCALE_INPUT:
|
|
|
|
|
height *= pass->fbo.scale_y;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RARCH_SCALE_VIEWPORT:
|
|
|
|
|
height = wiiu->vp.height * pass->fbo.scale_y;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RARCH_SCALE_ABSOLUTE:
|
|
|
|
|
height = pass->fbo.abs_y;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!width)
|
|
|
|
|
width = wiiu->color_buffer.surface.width;
|
|
|
|
|
|
|
|
|
|
if (!height)
|
|
|
|
|
height = wiiu->color_buffer.surface.height;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&wiiu->pass[i].texture, 0, sizeof(wiiu->pass[i].texture));
|
|
|
|
|
wiiu->pass[i].texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
|
|
|
|
wiiu->pass[i].texture.surface.width = width;
|
|
|
|
|
wiiu->pass[i].texture.surface.height = height;
|
|
|
|
|
wiiu->pass[i].texture.surface.depth = 1;
|
|
|
|
|
// wiiu->pass[i].texture.surface.mipLevels = 1;
|
|
|
|
|
wiiu->pass[i].texture.surface.format = pass->fbo.fp_fbo? GX2_SURFACE_FORMAT_FLOAT_R32_G32_B32_A32 :
|
|
|
|
|
pass->fbo.srgb_fbo? GX2_SURFACE_FORMAT_SRGB_R8_G8_B8_A8 :
|
|
|
|
|
GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
|
|
|
|
wiiu->pass[i].texture.surface.use = (GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER);
|
|
|
|
|
wiiu->pass[i].texture.viewNumSlices = 1;
|
|
|
|
|
wiiu->pass[i].texture.compMap = GX2_COMP_SEL(_R, _G, _B, _A);
|
|
|
|
|
|
|
|
|
|
GX2CalcSurfaceSizeAndAlignment(&wiiu->pass[i].texture.surface);
|
|
|
|
|
GX2InitTextureRegs(&wiiu->pass[i].texture);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if((i != (wiiu->shader_preset->passes - 1)) || (width != wiiu->vp.width) || (height != wiiu->vp.height))
|
|
|
|
|
{
|
|
|
|
|
wiiu->pass[i].texture.surface.image = MEM1_alloc(wiiu->pass[i].texture.surface.imageSize,
|
|
|
|
|
wiiu->pass[i].texture.surface.alignment);
|
|
|
|
|
|
|
|
|
|
if (!wiiu->pass[i].texture.surface.image)
|
|
|
|
|
{
|
|
|
|
|
printf("failed to allocate Render target memory from MEM1. falling back to stock.\n");
|
|
|
|
|
wiiu_free_shader_preset(wiiu);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(wiiu->pass[i].texture.surface.image, 0x00, wiiu->pass[i].texture.surface.imageSize);
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->pass[i].texture.surface.image,
|
|
|
|
|
wiiu->pass[i].texture.surface.imageSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(&wiiu->pass[i].color_buffer, 0, sizeof(wiiu->pass[i].color_buffer));
|
|
|
|
|
wiiu->pass[i].color_buffer.surface = wiiu->pass[i].texture.surface;
|
|
|
|
|
GX2InitColorBufferRegs(&wiiu->pass[i].color_buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool wiiu_gfx_frame(void *data, const void *frame,
|
|
|
|
|
unsigned width, unsigned height, uint64_t frame_count,
|
|
|
|
|
unsigned pitch, const char *msg, video_frame_info_t *video_info)
|
|
|
|
@ -688,8 +823,11 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static u32 last_frame_tick;
|
|
|
|
|
|
|
|
|
|
if (!(wiiu->menu.enable))
|
|
|
|
|
printf("frame time : %10.6f ms \r", (float)(currentTick - last_frame_tick) * 1000.0f / (float)wiiu_timer_clock);
|
|
|
|
|
printf("frame time : %10.6f ms \r",
|
|
|
|
|
(float)(currentTick - last_frame_tick) * 1000.0f / (float)wiiu_timer_clock);
|
|
|
|
|
|
|
|
|
|
last_frame_tick = currentTick;
|
|
|
|
|
printf("fps: %8.8f frames : %5i\r", fps, wiiu->frames++);
|
|
|
|
|
fflush(stdout);
|
|
|
|
@ -704,11 +842,9 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
|
|
|
|
|
if (frame)
|
|
|
|
|
{
|
|
|
|
|
if (width > wiiu->texture.surface.width)
|
|
|
|
|
width = wiiu->texture.surface.width;
|
|
|
|
|
|
|
|
|
|
if (height > wiiu->texture.surface.height)
|
|
|
|
|
height = wiiu->texture.surface.height;
|
|
|
|
|
if((width != wiiu->texture.surface.width) ||
|
|
|
|
|
(height != wiiu->texture.surface.height))
|
|
|
|
|
wiiu_init_frame_textures(wiiu, width, height);
|
|
|
|
|
|
|
|
|
|
wiiu->width = width;
|
|
|
|
|
wiiu->height = height;
|
|
|
|
@ -721,8 +857,10 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint32_t j;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
|
dst[j] = src[j];
|
|
|
|
|
|
|
|
|
|
dst += wiiu->texture.surface.pitch;
|
|
|
|
|
src += pitch / 4;
|
|
|
|
|
}
|
|
|
|
@ -735,8 +873,10 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
|
{
|
|
|
|
|
unsigned j;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
|
dst[j] = __builtin_bswap16(src[j]);
|
|
|
|
|
|
|
|
|
|
dst += wiiu->texture.surface.pitch;
|
|
|
|
|
src += pitch / 2;
|
|
|
|
|
}
|
|
|
|
@ -750,29 +890,153 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
|
|
|
|
GX2SetShader(&frame_shader);
|
|
|
|
|
|
|
|
|
|
GX2SetFetchShader(&frame_shader.fs);
|
|
|
|
|
GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset, frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp);
|
|
|
|
|
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
|
|
|
|
|
|
|
|
|
GX2Texture *texture = &wiiu->texture;
|
|
|
|
|
|
|
|
|
|
if (wiiu->shader_preset)
|
|
|
|
|
{
|
|
|
|
|
if(!wiiu->pass[0].texture.surface.image)
|
|
|
|
|
wiiu_init_frame_textures(wiiu, width, height);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
GX2SetVertexShader(wiiu->pass[i].gfd->vs);
|
|
|
|
|
GX2SetPixelShader(wiiu->pass[i].gfd->ps);
|
|
|
|
|
|
|
|
|
|
// if (wiiu->pass[i].gfd->vs->uniformBlockCount > 0)
|
|
|
|
|
// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[0].offset, wiiu->pass[i].gfd->vs->uniformBlocks[0].size, wiiu->ubo_mvp);
|
|
|
|
|
|
|
|
|
|
// GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
|
|
|
|
|
|
|
|
|
// if(wiiu->pass[i].vs_ubo)
|
|
|
|
|
// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[1].offset,
|
|
|
|
|
// wiiu->pass[i].gfd->vs->uniformBlocks[1].size,
|
|
|
|
|
// wiiu->pass[i].vs_ubo);
|
|
|
|
|
|
|
|
|
|
if (wiiu->pass[i].ps_ubo)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < wiiu->pass[i].gfd->ps->uniformVarCount; j++)
|
|
|
|
|
{
|
|
|
|
|
if (wiiu->pass[i].gfd->ps->uniformVars[j].block != 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const char *id = strrchr(wiiu->pass[i].gfd->ps->uniformVars[j].name, '.');
|
|
|
|
|
|
|
|
|
|
if (!id)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
id++;
|
|
|
|
|
|
|
|
|
|
float *dst = wiiu->pass[i].ps_ubo + wiiu->pass[i].gfd->ps->uniformVars[j].offset;
|
|
|
|
|
|
|
|
|
|
if (!strcmp(id, "OutputSize"))
|
|
|
|
|
{
|
|
|
|
|
((GX2_vec4 *)dst)->x = wiiu->pass[i].color_buffer.surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->y = wiiu->pass[i].color_buffer.surface.height;
|
|
|
|
|
((GX2_vec4 *)dst)->z = 1.0f / wiiu->pass[i].color_buffer.surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->w = 1.0f / wiiu->pass[i].color_buffer.surface.height;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcmp(id, "OriginalSize"))
|
|
|
|
|
{
|
|
|
|
|
((GX2_vec4 *)dst)->x = wiiu->texture.surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->y = wiiu->texture.surface.height;
|
|
|
|
|
((GX2_vec4 *)dst)->z = 1.0f / wiiu->texture.surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->w = 1.0f / wiiu->texture.surface.height;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcmp(id, "SourceSize"))
|
|
|
|
|
{
|
|
|
|
|
((GX2_vec4 *)dst)->x = texture->surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->y = texture->surface.height;
|
|
|
|
|
((GX2_vec4 *)dst)->z = 1.0f / texture->surface.width;
|
|
|
|
|
((GX2_vec4 *)dst)->w = 1.0f / texture->surface.height;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int k = 0; k < wiiu->shader_preset->num_parameters; k++)
|
|
|
|
|
{
|
|
|
|
|
if (!strcmp(id, wiiu->shader_preset->parameters[k].id))
|
|
|
|
|
{
|
|
|
|
|
*dst = wiiu->shader_preset->parameters[k].current;
|
|
|
|
|
*(u32 *)dst = __builtin_bswap32(*(u32 *)dst);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo,
|
|
|
|
|
wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
|
|
|
|
|
|
|
|
|
GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[0].offset,
|
|
|
|
|
wiiu->pass[i].gfd->ps->uniformBlocks[0].size, wiiu->pass[i].ps_ubo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GX2SetPixelTexture(texture, wiiu->pass[i].gfd->ps->samplerVars[0].location);
|
|
|
|
|
GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? &wiiu->sampler_linear : &wiiu->sampler_nearest,
|
|
|
|
|
wiiu->pass[i].gfd->ps->samplerVars[0].location);
|
|
|
|
|
|
|
|
|
|
if(wiiu->pass[i].color_buffer.surface.image)
|
|
|
|
|
{
|
|
|
|
|
GX2SetColorBuffer(&wiiu->pass[i].color_buffer, GX2_RENDER_TARGET_0);
|
|
|
|
|
GX2SetViewport(0.0f, 0.0f, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height, 0.0f,
|
|
|
|
|
1.0f);
|
|
|
|
|
GX2SetScissor(0, 0, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height);
|
|
|
|
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
|
|
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_TEXTURE, wiiu->pass[i].texture.surface.image,
|
|
|
|
|
wiiu->pass[i].texture.surface.imageSize);
|
|
|
|
|
texture = &wiiu->pass[i].texture;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
texture = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(texture)
|
|
|
|
|
{
|
|
|
|
|
GX2SetVertexShader(&frame_shader.vs);
|
|
|
|
|
GX2SetPixelShader(&frame_shader.ps);
|
|
|
|
|
GX2SetPixelTexture(texture, frame_shader.ps.samplerVars[0].location);
|
|
|
|
|
GX2SetPixelSampler(wiiu->smooth ? &wiiu->sampler_linear : &wiiu->sampler_nearest,
|
|
|
|
|
frame_shader.ps.samplerVars[0].location);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GX2SetViewport(wiiu->vp.x, wiiu->vp.y, wiiu->vp.width, wiiu->vp.height, 0.0f, 1.0f);
|
|
|
|
|
GX2SetScissor(wiiu->vp.x, wiiu->vp.y, wiiu->vp.width, wiiu->vp.height);
|
|
|
|
|
|
|
|
|
|
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
|
|
|
|
GX2SetPixelTexture(&wiiu->texture, frame_shader.ps.samplerVars[0].location);
|
|
|
|
|
GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest, frame_shader.ps.samplerVars[0].location);
|
|
|
|
|
|
|
|
|
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GX2SetShaderMode(GX2_SHADER_MODE_GEOMETRY_SHADER);
|
|
|
|
|
GX2SetShader(&sprite_shader);
|
|
|
|
|
GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer, wiiu->input_ring_buffer_size);
|
|
|
|
|
GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer, wiiu->output_ring_buffer_size);
|
|
|
|
|
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, sprite_shader.vs.uniformBlocks[0].size, wiiu->ubo_vp);
|
|
|
|
|
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size, wiiu->ubo_tex);
|
|
|
|
|
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, sprite_shader.vs.uniformBlocks[0].size,
|
|
|
|
|
wiiu->ubo_vp);
|
|
|
|
|
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size,
|
|
|
|
|
wiiu->ubo_tex);
|
|
|
|
|
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f);
|
|
|
|
|
GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_OVERLAY
|
|
|
|
|
|
|
|
|
|
if (wiiu->overlay_enable)
|
|
|
|
|
gx2_render_overlay(wiiu);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (wiiu->menu.enable)
|
|
|
|
@ -802,6 +1066,7 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER,
|
|
|
|
|
wiiu->vertex_cache.v, wiiu->vertex_cache.current * sizeof(*wiiu->vertex_cache.v));
|
|
|
|
|
|
|
|
|
|
if (wiiu->menu.enable)
|
|
|
|
|
GX2DrawDone();
|
|
|
|
|
|
|
|
|
@ -847,17 +1112,108 @@ static bool wiiu_gfx_suppress_screensaver(void* data, bool enable)
|
|
|
|
|
static bool wiiu_gfx_set_shader(void *data,
|
|
|
|
|
enum rarch_shader_type type, const char *path)
|
|
|
|
|
{
|
|
|
|
|
(void)data;
|
|
|
|
|
(void)type;
|
|
|
|
|
(void)path;
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *)data;
|
|
|
|
|
|
|
|
|
|
if (!wiiu)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
GX2DrawDone();
|
|
|
|
|
wiiu_free_shader_preset(wiiu);
|
|
|
|
|
|
|
|
|
|
if (type != RARCH_SHADER_SLANG && path)
|
|
|
|
|
{
|
|
|
|
|
RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n");
|
|
|
|
|
path = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
config_file_t *conf = config_file_new(path);
|
|
|
|
|
|
|
|
|
|
if (!conf)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
wiiu->shader_preset = calloc(1, sizeof(*wiiu->shader_preset));
|
|
|
|
|
|
|
|
|
|
if (!video_shader_read_conf_cgp(conf, wiiu->shader_preset))
|
|
|
|
|
{
|
|
|
|
|
free(wiiu->shader_preset);
|
|
|
|
|
wiiu->shader_preset = NULL;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
config_file_free(conf);
|
|
|
|
|
|
|
|
|
|
video_shader_resolve_relative(wiiu->shader_preset, path);
|
|
|
|
|
|
|
|
|
|
// video_shader_resolve_parameters(conf, &shader);
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
slang_preprocess_parse_parameters(wiiu->shader_preset->pass[i].source.path, wiiu->shader_preset);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
|
|
|
|
{
|
|
|
|
|
char gfdpath[PATH_MAX_LENGTH];
|
|
|
|
|
struct video_shader_pass *pass = &wiiu->shader_preset->pass[i];
|
|
|
|
|
|
|
|
|
|
strncpy(gfdpath, pass->source.path, PATH_MAX_LENGTH);
|
|
|
|
|
|
|
|
|
|
char *ptr = strrchr(gfdpath, '.');
|
|
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
|
ptr = gfdpath + strlen(gfdpath);
|
|
|
|
|
|
|
|
|
|
*ptr++ = '.';
|
|
|
|
|
*ptr++ = 'g';
|
|
|
|
|
*ptr++ = 's';
|
|
|
|
|
*ptr++ = 'h';
|
|
|
|
|
*ptr++ = '\0';
|
|
|
|
|
|
|
|
|
|
wiiu->pass[i].gfd = gfd_open(gfdpath);
|
|
|
|
|
|
|
|
|
|
if (!wiiu->pass[i].gfd)
|
|
|
|
|
{
|
|
|
|
|
wiiu_free_shader_preset(wiiu);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wiiu->pass[i].gfd->vs->uniformBlockCount > 1)
|
|
|
|
|
{
|
|
|
|
|
wiiu->pass[i].vs_ubo = MEM2_alloc(wiiu->pass[i].gfd->vs->uniformBlocks[1].size, GX2_UNIFORM_BLOCK_ALIGNMENT);
|
|
|
|
|
memset(wiiu->pass[i].vs_ubo, 0, wiiu->pass[i].gfd->vs->uniformBlocks[1].size);
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].vs_ubo,
|
|
|
|
|
wiiu->pass[i].gfd->vs->uniformBlocks[1].size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wiiu->pass[i].gfd->ps->uniformBlockCount > 0)
|
|
|
|
|
{
|
|
|
|
|
wiiu->pass[i].ps_ubo = MEM2_alloc(wiiu->pass[i].gfd->ps->uniformBlocks[0].size, GX2_UNIFORM_BLOCK_ALIGNMENT);
|
|
|
|
|
memset(wiiu->pass[i].ps_ubo, 0, wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo,
|
|
|
|
|
wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct video_shader *wiiu_gfx_get_current_shader(void *data)
|
|
|
|
|
{
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *)data;
|
|
|
|
|
|
|
|
|
|
if (!wiiu)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return wiiu->shader_preset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void wiiu_gfx_set_rotation(void *data,
|
|
|
|
|
unsigned rotation)
|
|
|
|
|
{
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *) data;
|
|
|
|
|
|
|
|
|
|
if (wiiu)
|
|
|
|
|
{
|
|
|
|
|
wiiu->rotation = rotation;
|
|
|
|
@ -870,6 +1226,7 @@ static void wiiu_gfx_viewport_info(void* data,
|
|
|
|
|
struct video_viewport *vp)
|
|
|
|
|
{
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *) data;
|
|
|
|
|
|
|
|
|
|
if (wiiu)
|
|
|
|
|
*vp = wiiu->vp;
|
|
|
|
|
}
|
|
|
|
@ -929,6 +1286,7 @@ static void wiiu_gfx_unload_texture(void* data, uintptr_t handle)
|
|
|
|
|
static void wiiu_gfx_set_filtering(void *data, unsigned index, bool smooth)
|
|
|
|
|
{
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *) data;
|
|
|
|
|
|
|
|
|
|
if (wiiu)
|
|
|
|
|
wiiu->smooth = smooth;
|
|
|
|
|
}
|
|
|
|
@ -994,6 +1352,7 @@ static void wiiu_gfx_set_texture_enable(void* data, bool state, bool full_screen
|
|
|
|
|
{
|
|
|
|
|
(void) full_screen;
|
|
|
|
|
wiiu_video_t *wiiu = (wiiu_video_t *) data;
|
|
|
|
|
|
|
|
|
|
if (wiiu)
|
|
|
|
|
wiiu->menu.enable = state;
|
|
|
|
|
|
|
|
|
@ -1036,7 +1395,7 @@ static const video_poke_interface_t wiiu_poke_interface =
|
|
|
|
|
wiiu_gfx_set_osd_msg,
|
|
|
|
|
NULL, /* show_mouse */
|
|
|
|
|
NULL, /* grab_mouse_toggle */
|
|
|
|
|
NULL, /* get_current_shader */
|
|
|
|
|
wiiu_gfx_get_current_shader,
|
|
|
|
|
NULL, /* get_current_software_framebuffer */
|
|
|
|
|
NULL, /* get_hw_render_interface */
|
|
|
|
|
};
|
|
|
|
|