2016-10-27 00:34:10 +00:00
|
|
|
/* RetroArch - A frontend for libretro.
|
|
|
|
* Copyright (C) 2014-2016 - Ali Bouhlel
|
|
|
|
*
|
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "../../driver.h"
|
|
|
|
#include "../../configuration.h"
|
|
|
|
#include "../../verbosity.h"
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
#include <string.h>
|
2016-10-29 01:56:40 +00:00
|
|
|
#include <coreinit/screen.h>
|
|
|
|
#include <coreinit/cache.h>
|
2016-11-05 14:05:46 +00:00
|
|
|
#include "gx2.h"
|
2016-10-27 00:34:10 +00:00
|
|
|
#include "system/memory.h"
|
2016-11-05 14:05:46 +00:00
|
|
|
#include "tex_shader.h"
|
2016-10-27 00:34:10 +00:00
|
|
|
|
|
|
|
#include "wiiu_dbg.h"
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
#define _X 0x00
|
|
|
|
#define _Y 0x01
|
|
|
|
#define _Z 0x02
|
|
|
|
#define _W 0x03
|
|
|
|
#define _R 0x00
|
|
|
|
#define _G 0x01
|
|
|
|
#define _B 0x02
|
|
|
|
#define _A 0x03
|
|
|
|
#define _0 0x04
|
|
|
|
#define _1 0x05
|
|
|
|
#define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3))
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
GX2TVRenderMode mode;
|
|
|
|
} wiiu_render_mode_t;
|
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2016-11-05 14:05:46 +00:00
|
|
|
float x;
|
|
|
|
float y;
|
|
|
|
}position_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
float u;
|
|
|
|
float v;
|
|
|
|
}tex_coord_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
tex_shader_t* shader;
|
2016-10-27 00:34:10 +00:00
|
|
|
struct
|
|
|
|
{
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2Texture texture;
|
2016-10-27 00:34:10 +00:00
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
bool enable;
|
2016-11-05 14:05:46 +00:00
|
|
|
position_t* position;
|
|
|
|
tex_coord_t* tex_coord;
|
2016-10-27 22:02:40 +00:00
|
|
|
} menu;
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2Sampler sampler_nearest;
|
|
|
|
GX2Sampler sampler_linear;
|
|
|
|
GX2Texture texture;
|
|
|
|
position_t* position;
|
|
|
|
tex_coord_t* tex_coord;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
|
|
|
|
|
|
|
|
void* drc_scan_buffer;
|
|
|
|
void* tv_scan_buffer;
|
|
|
|
GX2ColorBuffer color_buffer;
|
|
|
|
GX2ContextState* ctx_state;
|
|
|
|
void* cmd_buffer;
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
wiiu_render_mode_t render_mode;
|
|
|
|
int frames;
|
2016-10-27 22:02:40 +00:00
|
|
|
} wiiu_video_t;
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
static const wiiu_render_mode_t wiiu_render_mode_map[] =
|
|
|
|
{
|
|
|
|
{0}, /* GX2_TV_SCAN_MODE_NONE */
|
|
|
|
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_576I */
|
|
|
|
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_480I */
|
|
|
|
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_480P */
|
|
|
|
{1280, 720, GX2_TV_RENDER_MODE_WIDE_720P}, /* GX2_TV_SCAN_MODE_720P */
|
|
|
|
{0}, /* GX2_TV_SCAN_MODE_unk */
|
|
|
|
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P}, /* GX2_TV_SCAN_MODE_1080I */
|
|
|
|
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P} /* GX2_TV_SCAN_MODE_1080P */
|
|
|
|
};
|
|
|
|
|
|
|
|
static wiiu_set_position(position_t* position, GX2ColorBuffer* draw_buffer, float x0, float y0, float x1, float y1)
|
|
|
|
{
|
|
|
|
position[0].x = -1.0f;
|
|
|
|
position[0].y = -1.0f;
|
|
|
|
position[1].x = 1.0f;
|
|
|
|
position[1].y = -1.0f;
|
|
|
|
position[2].x = 1.0f;
|
|
|
|
position[2].y = 1.0f;
|
|
|
|
position[3].x = -1.0f;
|
|
|
|
position[3].y = 1.0f;
|
|
|
|
|
|
|
|
DEBUG_FLOAT(position[0].x);
|
|
|
|
DEBUG_FLOAT(position[0].y);
|
|
|
|
DEBUG_FLOAT(position[1].x);
|
|
|
|
DEBUG_FLOAT(position[1].y);
|
|
|
|
DEBUG_FLOAT(position[2].x);
|
|
|
|
DEBUG_FLOAT(position[2].y);
|
|
|
|
DEBUG_FLOAT(position[3].x);
|
|
|
|
DEBUG_FLOAT(position[3].y);
|
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, position, 4 * sizeof(*position));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wiiu_set_tex_coords(tex_coord_t* tex_coord, GX2Texture* texture, float u0, float v0, float u1, float v1)
|
|
|
|
{
|
|
|
|
tex_coord[0].u = u0 / texture->surface.width;
|
|
|
|
tex_coord[0].v = (v1 / texture->surface.height);
|
|
|
|
tex_coord[1].u = u1 / texture->surface.width;
|
|
|
|
tex_coord[1].v = (v1 / texture->surface.height);
|
|
|
|
tex_coord[2].u = u1 / texture->surface.width;
|
|
|
|
tex_coord[2].v = (v0 / texture->surface.height);
|
|
|
|
tex_coord[3].u = u0 / texture->surface.width;
|
|
|
|
tex_coord[3].v = (v0 / texture->surface.height);
|
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, tex_coord, 4 * sizeof(*tex_coord));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void* wiiu_gfx_init(const video_info_t* video,
|
|
|
|
const input_driver_t** input, void** input_data)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
2016-11-05 14:05:46 +00:00
|
|
|
int i;
|
2016-10-27 00:34:10 +00:00
|
|
|
*input = NULL;
|
|
|
|
*input_data = NULL;
|
|
|
|
|
|
|
|
wiiu_video_t* wiiu = calloc(1, sizeof(*wiiu));
|
2016-10-27 22:02:40 +00:00
|
|
|
|
|
|
|
if (!wiiu)
|
2016-10-27 00:34:10 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
/* video init */
|
|
|
|
wiiu->cmd_buffer = MEM2_alloc(0x400000, 0x40);
|
|
|
|
u32 init_attributes[] =
|
|
|
|
{
|
|
|
|
GX2_INIT_CMD_BUF_BASE, (u32)wiiu->cmd_buffer,
|
|
|
|
GX2_INIT_CMD_BUF_POOL_SIZE, 0x400000,
|
|
|
|
GX2_INIT_ARGC, 0,
|
|
|
|
GX2_INIT_ARGV, 0,
|
|
|
|
GX2_INIT_END
|
|
|
|
};
|
|
|
|
GX2Init(init_attributes);
|
|
|
|
|
|
|
|
/* setup scanbuffers */
|
|
|
|
u32 size = 0;
|
|
|
|
u32 tmp = 0;
|
|
|
|
wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()];
|
|
|
|
GX2CalcTVSize(wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size, &tmp);
|
|
|
|
wiiu->tv_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->tv_scan_buffer, size);
|
|
|
|
GX2SetTVBuffer(wiiu->tv_scan_buffer, size, wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
|
|
|
|
GX2_BUFFERING_MODE_DOUBLE);
|
|
|
|
|
|
|
|
GX2CalcDRCSize(GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size,
|
|
|
|
&tmp);
|
|
|
|
wiiu->drc_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->drc_scan_buffer, size);
|
|
|
|
GX2SetDRCBuffer(wiiu->drc_scan_buffer, size, GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
|
|
|
|
GX2_BUFFERING_MODE_DOUBLE);
|
|
|
|
|
|
|
|
memset(&wiiu->color_buffer, 0, sizeof(GX2ColorBuffer));
|
|
|
|
wiiu->color_buffer.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
|
|
|
wiiu->color_buffer.surface.width = wiiu->render_mode.width;
|
|
|
|
wiiu->color_buffer.surface.height = wiiu->render_mode.height;
|
|
|
|
wiiu->color_buffer.surface.depth = 1;
|
|
|
|
wiiu->color_buffer.surface.mipLevels = 1;
|
|
|
|
wiiu->color_buffer.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
|
|
|
wiiu->color_buffer.surface.use = GX2_SURFACE_USE_TEXTURE_COLOR_BUFFER_TV;
|
|
|
|
wiiu->color_buffer.viewNumSlices = 1;
|
|
|
|
GX2CalcSurfaceSizeAndAlignment(&wiiu->color_buffer.surface);
|
|
|
|
GX2InitColorBufferRegs(&wiiu->color_buffer);
|
|
|
|
|
|
|
|
wiiu->color_buffer.surface.image = MEM1_alloc(wiiu->color_buffer.surface.imageSize,
|
|
|
|
wiiu->color_buffer.surface.alignment);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->color_buffer.surface.image, wiiu->color_buffer.surface.imageSize);
|
|
|
|
|
|
|
|
wiiu->ctx_state = (GX2ContextState*)MEM2_alloc(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
|
|
|
|
GX2SetupContextStateEx(wiiu->ctx_state, GX2_TRUE);
|
|
|
|
|
|
|
|
GX2SetContextState(wiiu->ctx_state);
|
|
|
|
GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
|
|
|
|
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);
|
|
|
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
|
|
|
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
|
|
|
|
#if 0
|
|
|
|
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);
|
|
|
|
#else
|
|
|
|
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD,
|
|
|
|
GX2_DISABLE, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD);
|
|
|
|
#endif
|
|
|
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE);
|
|
|
|
GX2SetSwapInterval(1);
|
|
|
|
|
|
|
|
/* init shader */
|
|
|
|
|
|
|
|
|
|
|
|
// wiiu->shader = MEM2_alloc(sizeof(*wiiu->shader), GX2_VERTEX_BUFFER_ALIGNMENT);
|
|
|
|
wiiu->shader = MEM2_alloc(sizeof(tex_shader), 0x1000);
|
|
|
|
memcpy(wiiu->shader, &tex_shader, sizeof(tex_shader));
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->shader, sizeof(tex_shader));
|
|
|
|
|
|
|
|
wiiu->shader->vs.program = MEM2_alloc(wiiu->shader->vs.size, GX2_SHADER_ALIGNMENT);
|
|
|
|
memcpy(wiiu->shader->vs.program, tex_shader.vs.program, wiiu->shader->vs.size);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->vs.program, wiiu->shader->vs.size);
|
|
|
|
wiiu->shader->vs.attribVars = MEM2_alloc(wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar),
|
|
|
|
GX2_SHADER_ALIGNMENT);
|
|
|
|
memcpy(wiiu->shader->vs.attribVars, tex_shader.vs.attribVars ,
|
|
|
|
wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar));
|
|
|
|
|
|
|
|
wiiu->shader->ps.program = MEM2_alloc(wiiu->shader->ps.size, GX2_SHADER_ALIGNMENT);
|
|
|
|
memcpy(wiiu->shader->ps.program, tex_shader.ps.program, wiiu->shader->ps.size);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->ps.program, wiiu->shader->ps.size);
|
|
|
|
wiiu->shader->ps.samplerVars = MEM2_alloc(wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar),
|
|
|
|
GX2_SHADER_ALIGNMENT);
|
|
|
|
memcpy(wiiu->shader->ps.samplerVars, tex_shader.ps.samplerVars,
|
|
|
|
wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar));
|
|
|
|
|
|
|
|
wiiu->shader->fs.size = GX2CalcFetchShaderSizeEx(2, GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
|
|
|
|
wiiu->shader->fs.program = MEM2_alloc(wiiu->shader->fs.size, GX2_SHADER_ALIGNMENT);
|
|
|
|
GX2InitFetchShaderEx(&wiiu->shader->fs, (uint8_t*)wiiu->shader->fs.program,
|
|
|
|
sizeof(wiiu->shader->attribute_stream) / sizeof(GX2AttribStream),
|
|
|
|
(GX2AttribStream*)&wiiu->shader->attribute_stream,
|
|
|
|
GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->fs.program, wiiu->shader->fs.size);
|
|
|
|
|
|
|
|
GX2SetVertexShader(&wiiu->shader->vs);
|
|
|
|
GX2SetPixelShader(&wiiu->shader->ps);
|
|
|
|
GX2SetFetchShader(&wiiu->shader->fs);
|
|
|
|
|
|
|
|
wiiu->position = MEM2_alloc(4 * sizeof(*wiiu->position), GX2_VERTEX_BUFFER_ALIGNMENT);
|
|
|
|
wiiu_set_position(wiiu->position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
|
|
|
|
|
|
|
wiiu->tex_coord = MEM2_alloc(4 * sizeof(*wiiu->tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
|
|
|
|
wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, wiiu->texture.surface.width, wiiu->texture.surface.height);
|
|
|
|
|
|
|
|
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->position), sizeof(*wiiu->position), wiiu->position);
|
|
|
|
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord);
|
|
|
|
|
|
|
|
wiiu->menu.position = MEM2_alloc(4 * sizeof(*wiiu->menu.position), GX2_VERTEX_BUFFER_ALIGNMENT);
|
|
|
|
wiiu_set_position(wiiu->menu.position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
|
|
|
|
|
|
|
wiiu->menu.tex_coord = MEM2_alloc(4 * sizeof(*wiiu->menu.tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
|
|
|
|
wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height);
|
|
|
|
|
|
|
|
/* init 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.format = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
|
|
|
|
wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
|
|
|
wiiu->texture.viewNumSlices = 1;
|
|
|
|
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, 0x88, 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;
|
|
|
|
wiiu->menu.texture.surface.height = 512;
|
|
|
|
wiiu->menu.texture.surface.depth = 1;
|
|
|
|
wiiu->menu.texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
|
|
|
wiiu->menu.texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4;
|
|
|
|
wiiu->menu.texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
|
|
|
wiiu->menu.texture.viewNumSlices = 1;
|
|
|
|
wiiu->menu.texture.compMap = GX2_COMP_SEL(_A, _R, _G, _B);
|
|
|
|
GX2CalcSurfaceSizeAndAlignment(&wiiu->menu.texture.surface);
|
|
|
|
GX2InitTextureRegs(&wiiu->menu.texture);
|
|
|
|
|
|
|
|
wiiu->menu.texture.surface.image = MEM2_alloc(wiiu->menu.texture.surface.imageSize,
|
|
|
|
wiiu->menu.texture.surface.alignment);
|
|
|
|
|
|
|
|
for (i = 0; i < wiiu->menu.texture.surface.imageSize / 4; i++)
|
|
|
|
((uint32_t*)wiiu->menu.texture.surface.image)[i] = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
((uint32_t*)wiiu->menu.texture.surface.image)[0] = 0xFF0000FF;
|
|
|
|
DEBUG_VAR(wiiu->menu.texture.surface.width);
|
|
|
|
DEBUG_VAR(wiiu->menu.texture.surface.height);
|
|
|
|
DEBUG_VAR(wiiu->menu.texture.surface.alignment);
|
|
|
|
DEBUG_VAR(wiiu->menu.texture.surface.imageSize);
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->menu.texture.surface.image,
|
|
|
|
wiiu->menu.texture.surface.imageSize);
|
|
|
|
|
|
|
|
/* init samplers */
|
|
|
|
GX2InitSampler(&wiiu->sampler_nearest, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
|
|
|
|
GX2InitSampler(&wiiu->sampler_linear, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
|
|
|
|
|
|
|
|
|
|
|
/* set Texture and Sampler */
|
|
|
|
GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
|
|
|
|
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
|
|
|
|
|
|
|
|
GX2SetTVEnable(GX2_ENABLE);
|
|
|
|
GX2SetDRCEnable(GX2_ENABLE);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
|
|
|
if (input && input_data)
|
|
|
|
{
|
|
|
|
void* wiiuinput = NULL;
|
|
|
|
wiiuinput = input_wiiu.init();
|
|
|
|
*input = wiiuinput ? &input_wiiu : NULL;
|
|
|
|
*input_data = wiiuinput;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG_LINE();
|
|
|
|
|
|
|
|
return wiiu;
|
|
|
|
}
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_gfx_free(void* data)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
wiiu_video_t* wiiu = (wiiu_video_t*) data;
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
if (!wiiu)
|
2016-10-27 00:34:10 +00:00
|
|
|
return;
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2Flush();
|
|
|
|
GX2DrawDone();
|
|
|
|
GX2Shutdown();
|
|
|
|
|
|
|
|
GX2SetTVEnable(GX2_DISABLE);
|
|
|
|
GX2SetDRCEnable(GX2_DISABLE);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->ctx_state);
|
|
|
|
MEM2_free(wiiu->cmd_buffer);
|
|
|
|
MEM2_free(wiiu->texture.surface.image);
|
|
|
|
MEM2_free(wiiu->menu.texture.surface.image);
|
|
|
|
|
|
|
|
MEM1_free(wiiu->color_buffer.surface.image);
|
|
|
|
|
|
|
|
MEMBucket_free(wiiu->tv_scan_buffer);
|
|
|
|
MEMBucket_free(wiiu->drc_scan_buffer);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->shader->vs.program);
|
|
|
|
MEM2_free(wiiu->shader->vs.attribVars);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->shader->ps.program);
|
|
|
|
MEM2_free(wiiu->shader->ps.samplerVars);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->shader->fs.program);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->shader);
|
|
|
|
|
|
|
|
MEM2_free(wiiu->position);
|
|
|
|
MEM2_free(wiiu->tex_coord);
|
|
|
|
MEM2_free(wiiu->menu.position);
|
|
|
|
MEM2_free(wiiu->menu.tex_coord);
|
|
|
|
|
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
free(wiiu);
|
|
|
|
DEBUG_LINE();
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_frame(void* data, const void* frame,
|
|
|
|
unsigned width, unsigned height, uint64_t frame_count,
|
|
|
|
unsigned pitch, const char* msg)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)frame;
|
|
|
|
(void)width;
|
|
|
|
(void)height;
|
|
|
|
(void)pitch;
|
|
|
|
(void)msg;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
wiiu_video_t* wiiu = (wiiu_video_t*) data;
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
// GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.3f, 0.8f, 1.0f);
|
|
|
|
/* can't call GX2ClearColor after GX2SetContextState for whatever reason */
|
|
|
|
GX2SetContextState(wiiu->ctx_state);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
if (!width || !height)
|
|
|
|
{
|
|
|
|
GX2WaitForVsync();
|
|
|
|
return;
|
|
|
|
}
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
if(frame)
|
2016-10-27 22:02:40 +00:00
|
|
|
{
|
2016-11-05 14:05:46 +00:00
|
|
|
if (width > wiiu->texture.surface.width)
|
|
|
|
width = wiiu->texture.surface.width;
|
|
|
|
|
|
|
|
if (height > wiiu->texture.surface.height)
|
|
|
|
height = wiiu->texture.surface.height;
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
wiiu->width = width;
|
|
|
|
wiiu->height = height;
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
const uint16_t* src = frame;
|
|
|
|
uint16_t* dst = (uint16_t*)wiiu->texture.surface.image;
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
2016-10-27 22:02:40 +00:00
|
|
|
{
|
2016-11-05 14:05:46 +00:00
|
|
|
// memcpy(dst, src, width * sizeof(uint16_t));
|
|
|
|
int j;
|
|
|
|
for(j = 0; j < width; j++)
|
|
|
|
dst[j] = __builtin_bswap16(src[j]);
|
|
|
|
dst += wiiu->texture.surface.pitch;
|
|
|
|
src += pitch / 2;
|
2016-10-27 22:02:40 +00:00
|
|
|
}
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
|
|
|
|
wiiu->texture.surface.imageSize);
|
|
|
|
wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, width, height);
|
2016-10-27 22:02:40 +00:00
|
|
|
}
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->position), sizeof(*wiiu->position), wiiu->position);
|
|
|
|
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord);
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
|
|
|
|
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
if (wiiu->menu.enable)
|
|
|
|
{
|
|
|
|
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->menu.position), sizeof(*wiiu->menu.position), wiiu->menu.position);
|
|
|
|
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->menu.tex_coord), sizeof(*wiiu->menu.tex_coord), wiiu->menu.tex_coord);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2SetPixelTexture(&wiiu->menu.texture, wiiu->shader->sampler.location);
|
|
|
|
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
|
|
|
|
|
|
|
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
|
|
|
}
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
|
|
|
|
GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
GX2SwapScanBuffers();
|
|
|
|
GX2Flush();
|
|
|
|
GX2WaitForVsync();
|
|
|
|
printf("\rframe : %5i", wiiu->frames++);
|
|
|
|
fflush(stdout);
|
2016-10-27 00:34:10 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_gfx_set_nonblock_state(void* data, bool toggle)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)toggle;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_alive(void* data)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_focus(void* data)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_suppress_screensaver(void* data, bool enable)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)enable;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_has_windowed(void* data)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_set_shader(void* data,
|
|
|
|
enum rarch_shader_type type, const char* path)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)type;
|
|
|
|
(void)path;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_gfx_set_rotation(void* data,
|
|
|
|
unsigned rotation)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)rotation;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_gfx_viewport_info(void* data,
|
|
|
|
struct video_viewport* vp)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)vp;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static bool wiiu_gfx_read_viewport(void* data, uint8_t* buffer)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
(void)buffer;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static uintptr_t wiiu_load_texture(void* video_data, void* data,
|
|
|
|
bool threaded, enum texture_filter_type filter_type)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_unload_texture(void* data, uintptr_t handle)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
static void wiiu_set_filtering(void* data, unsigned index, bool smooth)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
static void wiiu_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
static void wiiu_apply_state_changes(void* data)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wiiu_viewport_info(void* data, struct video_viewport* vp)
|
|
|
|
{
|
|
|
|
vp->full_width = 800;
|
|
|
|
vp->full_height = 480;
|
|
|
|
vp->width = 800;
|
|
|
|
vp->height = 480;
|
|
|
|
vp->x = 0;
|
|
|
|
vp->y = 0;
|
|
|
|
}
|
|
|
|
static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32,
|
2016-10-27 22:02:40 +00:00
|
|
|
unsigned width, unsigned height, float alpha)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
wiiu_video_t* wiiu = (wiiu_video_t*) data;
|
2016-10-27 22:02:40 +00:00
|
|
|
|
|
|
|
if (!wiiu)
|
2016-10-27 00:34:10 +00:00
|
|
|
return;
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
if (!frame || !width || !height)
|
2016-10-27 00:34:10 +00:00
|
|
|
return;
|
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
if (width > wiiu->menu.texture.surface.width)
|
|
|
|
width = wiiu->menu.texture.surface.width;
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-11-05 14:05:46 +00:00
|
|
|
if (height > wiiu->menu.texture.surface.height)
|
|
|
|
height = wiiu->menu.texture.surface.height;
|
2016-10-27 00:34:10 +00:00
|
|
|
|
|
|
|
wiiu->menu.width = width;
|
|
|
|
wiiu->menu.height = height;
|
|
|
|
|
|
|
|
const uint16_t* src = frame;
|
2016-11-05 14:05:46 +00:00
|
|
|
uint16_t* dst = (uint16_t*)wiiu->menu.texture.surface.image;
|
|
|
|
|
|
|
|
DEBUG_VAR(width);
|
|
|
|
DEBUG_VAR(height);
|
2016-10-27 22:02:40 +00:00
|
|
|
|
2016-10-27 00:34:10 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
memcpy(dst, src, width * sizeof(uint16_t));
|
2016-11-05 14:05:46 +00:00
|
|
|
dst += wiiu->menu.texture.surface.pitch;
|
2016-10-27 00:34:10 +00:00
|
|
|
src += width;
|
|
|
|
}
|
2016-11-05 14:05:46 +00:00
|
|
|
|
|
|
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->menu.texture.surface.image,
|
|
|
|
wiiu->menu.texture.surface.imageSize);
|
|
|
|
|
|
|
|
wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, width, height);
|
|
|
|
// wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height);
|
2016-10-27 00:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void wiiu_set_texture_enable(void* data, bool state, bool full_screen)
|
|
|
|
{
|
|
|
|
(void) full_screen;
|
|
|
|
wiiu_video_t* wiiu = (wiiu_video_t*) data;
|
|
|
|
wiiu->menu.enable = state;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_set_osd_msg(void* data, const char* msg,
|
|
|
|
const struct font_params* params, void* font)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const video_poke_interface_t wiiu_poke_interface =
|
|
|
|
{
|
|
|
|
wiiu_load_texture,
|
|
|
|
wiiu_unload_texture,
|
|
|
|
NULL,
|
|
|
|
wiiu_set_filtering,
|
|
|
|
NULL, /* get_video_output_size */
|
|
|
|
NULL, /* get_video_output_prev */
|
|
|
|
NULL, /* get_video_output_next */
|
|
|
|
NULL, /* get_current_framebuffer */
|
|
|
|
NULL,
|
|
|
|
wiiu_set_aspect_ratio,
|
|
|
|
wiiu_apply_state_changes,
|
|
|
|
#ifdef HAVE_MENU
|
|
|
|
wiiu_set_texture_frame,
|
|
|
|
wiiu_set_texture_enable,
|
|
|
|
wiiu_set_osd_msg,
|
|
|
|
#endif
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2016-10-27 22:02:40 +00:00
|
|
|
static void wiiu_gfx_get_poke_interface(void* data,
|
|
|
|
const video_poke_interface_t** iface)
|
2016-10-27 00:34:10 +00:00
|
|
|
{
|
|
|
|
(void)data;
|
|
|
|
*iface = &wiiu_poke_interface;
|
|
|
|
}
|
|
|
|
|
|
|
|
video_driver_t video_wiiu =
|
|
|
|
{
|
|
|
|
wiiu_gfx_init,
|
|
|
|
wiiu_gfx_frame,
|
|
|
|
wiiu_gfx_set_nonblock_state,
|
|
|
|
wiiu_gfx_alive,
|
|
|
|
wiiu_gfx_focus,
|
|
|
|
wiiu_gfx_suppress_screensaver,
|
|
|
|
wiiu_gfx_has_windowed,
|
|
|
|
wiiu_gfx_set_shader,
|
|
|
|
wiiu_gfx_free,
|
|
|
|
"gx2",
|
|
|
|
NULL, /* set_viewport */
|
|
|
|
wiiu_gfx_set_rotation,
|
|
|
|
wiiu_gfx_viewport_info,
|
|
|
|
wiiu_gfx_read_viewport,
|
|
|
|
NULL, /* read_frame_raw */
|
|
|
|
#ifdef HAVE_OVERLAY
|
2016-10-27 22:02:40 +00:00
|
|
|
NULL, /* overlay_interface */
|
2016-10-27 00:34:10 +00:00
|
|
|
#endif
|
2016-10-27 22:02:40 +00:00
|
|
|
wiiu_gfx_get_poke_interface,
|
2016-10-27 00:34:10 +00:00
|
|
|
};
|