mirror of
https://github.com/libretro/RetroArch
synced 2025-03-05 19:13:45 +00:00
(WIIU) add a frame shader to match the shaders used by the gl/vulkan
drivers.
This commit is contained in:
parent
3979d03cb3
commit
8e095164e0
@ -69,6 +69,7 @@ else
|
||||
OBJ += wiiu/shader_utils.o
|
||||
OBJ += wiiu/tex_shader.o
|
||||
OBJ += wiiu/sprite_shader.o
|
||||
OBJ += wiiu/frame_shader.o
|
||||
|
||||
ifeq ($(GRIFFIN_BUILD), 1)
|
||||
OBJ += griffin/griffin.o
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <wiiu/gx2.h>
|
||||
|
||||
#include "wiiu/tex_shader.h"
|
||||
#include "wiiu/frame_shader.h"
|
||||
#include "wiiu/sprite_shader.h"
|
||||
|
||||
#undef _X
|
||||
@ -57,9 +57,10 @@ typedef struct
|
||||
GX2Sampler sampler_nearest;
|
||||
GX2Sampler sampler_linear;
|
||||
GX2Texture texture;
|
||||
tex_shader_vertex_t* v;
|
||||
frame_vertex_t* v;
|
||||
GX2_vec2* ubo_vp;
|
||||
GX2_vec2* ubo_tex;
|
||||
GX2_mat4x4* ubo_mvp;
|
||||
void* input_ring_buffer;
|
||||
u32 input_ring_buffer_size;
|
||||
void* output_ring_buffer;
|
||||
|
@ -51,64 +51,67 @@ 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_position(tex_shader_vertex_t* v, GX2ColorBuffer* draw_buffer, float x0, float y0, float x1, float y1)
|
||||
static void wiiu_set_tex_coords(frame_vertex_t* v, GX2Texture* texture, float u0, float v0, float u1, float v1, unsigned rotation)
|
||||
{
|
||||
v[0].pos.x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;
|
||||
v[0].pos.y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
|
||||
v[1].pos.x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
|
||||
v[1].pos.y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
|
||||
v[2].pos.x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
|
||||
v[2].pos.y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
|
||||
v[3].pos.x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;;
|
||||
v[3].pos.y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
|
||||
v[0].coord.u = u0 / texture->surface.width;
|
||||
v[0].coord.v = v0 / texture->surface.height;
|
||||
v[1].coord.u = u1 / texture->surface.width;
|
||||
v[1].coord.v = v0 / texture->surface.height;
|
||||
v[2].coord.u = u1 / texture->surface.width;
|
||||
v[2].coord.v = v1 / texture->surface.height;
|
||||
v[3].coord.u = u0 / texture->surface.width;
|
||||
v[3].coord.v = v1 / texture->surface.height;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, v, 4 * sizeof(*v));
|
||||
}
|
||||
|
||||
static void wiiu_set_tex_coords(tex_shader_vertex_t* v, GX2Texture* texture, float u0, float v0, float u1, float v1, unsigned rotation)
|
||||
static void wiiu_set_projection(wiiu_video_t *wiiu)
|
||||
{
|
||||
v[((0 + rotation) % 4)].coord.u = u0 / texture->surface.width;
|
||||
v[((0 + rotation) % 4)].coord.v = (v1 / texture->surface.height);
|
||||
v[((1 + rotation) % 4)].coord.u = u1 / texture->surface.width;
|
||||
v[((1 + rotation) % 4)].coord.v = (v1 / texture->surface.height);
|
||||
v[((2 + rotation) % 4)].coord.u = u1 / texture->surface.width;
|
||||
v[((2 + rotation) % 4)].coord.v = (v0 / texture->surface.height);
|
||||
v[((3 + rotation) % 4)].coord.u = u0 / texture->surface.width;
|
||||
v[((3 + rotation) % 4)].coord.v = (v0 / texture->surface.height);
|
||||
math_matrix_4x4 proj, rot;
|
||||
matrix_4x4_ortho(proj, 0, 1, 1, 0, -1, 1);
|
||||
matrix_4x4_rotate_z(rot, wiiu->rotation * -M_PI_2);
|
||||
matrix_4x4_multiply((*wiiu->ubo_mvp), rot, proj);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->ubo_mvp, sizeof(*wiiu->ubo_mvp));
|
||||
}
|
||||
|
||||
static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
float width = wiiu->vp.full_width;
|
||||
float height = wiiu->vp.full_height;
|
||||
settings_t *settings = config_get_ptr();
|
||||
float desired_aspect = video_driver_get_aspect_ratio();
|
||||
unsigned width, height;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned viewport_width = wiiu->color_buffer.surface.width;
|
||||
unsigned viewport_height = wiiu->color_buffer.surface.height;
|
||||
float device_aspect = (float)viewport_width / viewport_height;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if(wiiu->rotation & 0x1)
|
||||
desired_aspect = 1.0 / desired_aspect;
|
||||
video_driver_get_size(&width, &height);
|
||||
|
||||
if (settings->bools.video_scale_integer)
|
||||
{
|
||||
video_viewport_get_scaled_integer(&wiiu->vp, wiiu->vp.full_width,
|
||||
wiiu->vp.full_height, desired_aspect, wiiu->keep_aspect);
|
||||
video_viewport_get_scaled_integer(&wiiu->vp,
|
||||
viewport_width, viewport_height,
|
||||
video_driver_get_aspect_ratio(), wiiu->keep_aspect);
|
||||
viewport_width = wiiu->vp.width;
|
||||
viewport_height = wiiu->vp.height;
|
||||
}
|
||||
else if (wiiu->keep_aspect)
|
||||
{
|
||||
float desired_aspect = video_driver_get_aspect_ratio();
|
||||
|
||||
#if defined(HAVE_MENU)
|
||||
if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
struct video_viewport *custom = video_viewport_get_custom();
|
||||
const struct video_viewport *custom = video_viewport_get_custom();
|
||||
|
||||
x = custom->x;
|
||||
y = custom->y;
|
||||
width = custom->width;
|
||||
height = custom->height;
|
||||
/* Vulkan has top-left origin viewport. */
|
||||
x = custom->x;
|
||||
y = custom->y;
|
||||
viewport_width = custom->width;
|
||||
viewport_height = custom->height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
float delta;
|
||||
float device_aspect = ((float)wiiu->vp.full_width) / wiiu->vp.full_height;
|
||||
|
||||
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
|
||||
{
|
||||
@ -119,43 +122,34 @@ static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu)
|
||||
}
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
delta = (desired_aspect / device_aspect - 1.0f)
|
||||
delta = (desired_aspect / device_aspect - 1.0f)
|
||||
/ 2.0f + 0.5f;
|
||||
x = (int)roundf(width * (0.5f - delta));
|
||||
width = (unsigned)roundf(2.0f * width * delta);
|
||||
x = (int)roundf(viewport_width * (0.5f - delta));
|
||||
viewport_width = (unsigned)roundf(2.0f * viewport_width * delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (device_aspect / desired_aspect - 1.0f)
|
||||
delta = (device_aspect / desired_aspect - 1.0f)
|
||||
/ 2.0f + 0.5f;
|
||||
y = (int)roundf(height * (0.5f - delta));
|
||||
height = (unsigned)roundf(2.0f * height * delta);
|
||||
y = (int)roundf(viewport_height * (0.5f - delta));
|
||||
viewport_height = (unsigned)roundf(2.0f * viewport_height * delta);
|
||||
}
|
||||
}
|
||||
|
||||
wiiu->vp.x = x;
|
||||
wiiu->vp.y = y;
|
||||
wiiu->vp.width = width;
|
||||
wiiu->vp.height = height;
|
||||
wiiu->vp.width = viewport_width;
|
||||
wiiu->vp.height = viewport_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
wiiu->vp.x = wiiu->vp.y = 0;
|
||||
wiiu->vp.width = width;
|
||||
wiiu->vp.height = height;
|
||||
wiiu->vp.x = 0;
|
||||
wiiu->vp.y = 0;
|
||||
wiiu->vp.width = viewport_width;
|
||||
wiiu->vp.height = viewport_height;
|
||||
}
|
||||
|
||||
float scale_w = wiiu->color_buffer.surface.width / wiiu->render_mode.width;
|
||||
float scale_h = wiiu->color_buffer.surface.height / wiiu->render_mode.height;
|
||||
wiiu_set_position(wiiu->v, &wiiu->color_buffer,
|
||||
wiiu->vp.x * scale_w,
|
||||
wiiu->vp.y * scale_h,
|
||||
(wiiu->vp.x + wiiu->vp.width) * scale_w,
|
||||
(wiiu->vp.y + wiiu->vp.height) * scale_h);
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->v, 4 * sizeof(*wiiu->v));
|
||||
|
||||
wiiu->should_resize = false;
|
||||
wiiu_set_projection(wiiu);
|
||||
}
|
||||
|
||||
static void wiiu_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
|
||||
@ -277,20 +271,23 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
||||
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);
|
||||
|
||||
GX2InitShader(&tex_shader);
|
||||
GX2InitShader(&frame_shader);
|
||||
GX2InitShader(&sprite_shader);
|
||||
GX2SetShader(&tex_shader);
|
||||
GX2SetShader(&frame_shader);
|
||||
|
||||
wiiu->ubo_vp = MEM1_alloc(sizeof(*wiiu->ubo_vp), GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
wiiu->ubo_vp->width = wiiu->color_buffer.surface.width;
|
||||
wiiu->ubo_vp->height = wiiu->color_buffer.surface.height;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->ubo_vp, sizeof(*wiiu->ubo_vp));
|
||||
|
||||
wiiu->ubo_tex = MEM1_alloc(sizeof(*wiiu->ubo_tex), GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
wiiu->ubo_tex = MEM1_alloc(sizeof(*wiiu->ubo_tex), GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
wiiu->ubo_tex->width = 1.0;
|
||||
wiiu->ubo_tex->height = 1.0;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->ubo_tex, sizeof(*wiiu->ubo_tex));
|
||||
|
||||
wiiu->ubo_mvp = MEM1_alloc(sizeof(*wiiu->ubo_mvp), GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
wiiu_set_projection(wiiu);
|
||||
|
||||
wiiu->input_ring_buffer_size = GX2CalcGeometryShaderInputRingBufferSize(sprite_shader.vs.ringItemSize);
|
||||
wiiu->output_ring_buffer_size = GX2CalcGeometryShaderOutputRingBufferSize(sprite_shader.gs.ringItemSize);
|
||||
wiiu->input_ring_buffer = MEM1_alloc(wiiu->input_ring_buffer_size, 0x1000);
|
||||
@ -347,12 +344,19 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
||||
|
||||
wiiu->v = MEM2_alloc(4 * sizeof(*wiiu->v), GX2_VERTEX_BUFFER_ALIGNMENT);
|
||||
|
||||
wiiu_set_position(wiiu->v, &wiiu->color_buffer, 0, 0,
|
||||
wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
||||
wiiu->v[0].pos.x = 0.0f;
|
||||
wiiu->v[0].pos.y = 0.0f;
|
||||
wiiu->v[1].pos.x = 1.0f;
|
||||
wiiu->v[1].pos.y = 0.0f;
|
||||
wiiu->v[2].pos.x = 1.0f;
|
||||
wiiu->v[2].pos.y = 1.0f;
|
||||
wiiu->v[3].pos.x = 0.0f;
|
||||
wiiu->v[3].pos.y = 1.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->v, 4 * sizeof(*wiiu->v));
|
||||
|
||||
wiiu_set_tex_coords(wiiu->v, &wiiu->texture, 0, 0,
|
||||
wiiu->texture.surface.width, wiiu->texture.surface.height, wiiu->rotation);
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->v, 4 * sizeof(*wiiu->v));
|
||||
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
||||
|
||||
wiiu->menu.v = MEM2_alloc(4 * sizeof(*wiiu->menu.v), GX2_VERTEX_BUFFER_ALIGNMENT);
|
||||
@ -377,8 +381,8 @@ static void* wiiu_gfx_init(const video_info_t* video,
|
||||
GX2InitSampler(&wiiu->sampler_linear, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
||||
|
||||
/* set Texture and Sampler */
|
||||
GX2SetPixelTexture(&wiiu->texture, tex_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelSampler(&wiiu->sampler_linear, tex_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelTexture(&wiiu->texture, frame_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelSampler(&wiiu->sampler_linear, frame_shader.ps.samplerVars[0].location);
|
||||
|
||||
/* clear leftover image */
|
||||
GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
@ -608,7 +612,7 @@ static void wiiu_gfx_free(void* data)
|
||||
GX2SetTVEnable(GX2_DISABLE);
|
||||
GX2SetDRCEnable(GX2_DISABLE);
|
||||
|
||||
GX2DestroyShader(&tex_shader);
|
||||
GX2DestroyShader(&frame_shader);
|
||||
GX2DestroyShader(&sprite_shader);
|
||||
|
||||
MEM2_free(wiiu->ctx_state);
|
||||
@ -622,6 +626,7 @@ static void wiiu_gfx_free(void* data)
|
||||
MEM1_free(wiiu->color_buffer.surface.image);
|
||||
MEM1_free(wiiu->ubo_vp);
|
||||
MEM1_free(wiiu->ubo_tex);
|
||||
MEM1_free(wiiu->ubo_mvp);
|
||||
MEM1_free(wiiu->input_ring_buffer);
|
||||
MEM1_free(wiiu->output_ring_buffer);
|
||||
|
||||
@ -742,15 +747,17 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
||||
wiiu->texture.surface.imageSize);
|
||||
|
||||
wiiu_set_tex_coords(wiiu->v, &wiiu->texture, 0, 0, width, height, wiiu->rotation);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->v, 4 * sizeof(*wiiu->v));
|
||||
}
|
||||
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_REGISTER);
|
||||
GX2SetShader(&tex_shader);
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
GX2SetShader(&frame_shader);
|
||||
GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset, frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp);
|
||||
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, tex_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest, tex_shader.ps.samplerVars[0].location);
|
||||
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);
|
||||
|
||||
@ -760,6 +767,8 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
|
||||
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);
|
||||
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)
|
||||
@ -852,6 +861,7 @@ static void wiiu_gfx_set_rotation(void* data,
|
||||
if(wiiu)
|
||||
{
|
||||
wiiu->rotation = rotation;
|
||||
wiiu_set_projection(wiiu);
|
||||
wiiu->should_resize = true;
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static void menu_display_wiiu_draw(void *data)
|
||||
v->color = COLOR_RGBA(0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
|
||||
GX2SetPixelTexture(texture, tex_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelTexture(texture, sprite_shader.ps.samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, wiiu->vertex_cache.current, 1);
|
||||
|
||||
|
163
wiiu/frame_shader.c
Normal file
163
wiiu/frame_shader.c
Normal file
@ -0,0 +1,163 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2018 - 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 <stddef.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <wiiu/gx2/common.h>
|
||||
#include "frame_shader.h"
|
||||
#include "gx2_shader_inl.h"
|
||||
|
||||
__attribute__((aligned(GX2_SHADER_ALIGNMENT)))
|
||||
static struct
|
||||
{
|
||||
u64 cf[32];
|
||||
u64 alu[18];
|
||||
} vs_program =
|
||||
{
|
||||
{
|
||||
CALL_FS NO_BARRIER,
|
||||
ALU(32, 18) KCACHE0(CB1, _0_15),
|
||||
EXP_DONE(POS0, _R1, _x, _y, _0, _1),
|
||||
EXP_DONE(PARAM0, _R2, _x, _y, _z, _z) NO_BARRIER
|
||||
END_OF_PROGRAM
|
||||
},
|
||||
{
|
||||
ALU_MUL(__,_x, _R1,_w, KC0(3),_y),
|
||||
ALU_MUL(__,_y, _R1,_w, KC0(3),_x),
|
||||
ALU_MUL(__,_z, _R1,_w, KC0(3),_w),
|
||||
ALU_MUL(__,_w, _R1,_w, KC0(3),_z),
|
||||
ALU_MOV(_R0,_x, _R2,_x)
|
||||
ALU_LAST,
|
||||
ALU_MULADD(_R123,_x, _R1,_z, KC0(2),_y, ALU_SRC_PV,_x),
|
||||
ALU_MULADD(_R123,_y, _R1,_z, KC0(2),_x, ALU_SRC_PV,_y),
|
||||
ALU_MULADD(_R123,_z, _R1,_z, KC0(2),_w, ALU_SRC_PV,_z),
|
||||
ALU_MULADD(_R123,_w, _R1,_z, KC0(2),_z, ALU_SRC_PV,_w),
|
||||
ALU_MOV(_R0,_y, _R2,_y)
|
||||
ALU_LAST,
|
||||
ALU_MULADD(_R123,_x, _R1,_y, KC0(1),_y, ALU_SRC_PV,_x),
|
||||
ALU_MULADD(_R123,_y, _R1,_y, KC0(1),_x, ALU_SRC_PV,_y),
|
||||
ALU_MULADD(_R123,_z, _R1,_y, KC0(1),_w, ALU_SRC_PV,_z),
|
||||
ALU_MULADD(_R123,_w, _R1,_y, KC0(1),_z, ALU_SRC_PV,_w)
|
||||
ALU_LAST,
|
||||
ALU_MULADD(_R1,_x, _R1,_x, KC0(0),_x, ALU_SRC_PV,_y),
|
||||
ALU_MULADD(_R1,_y, _R1,_x, KC0(0),_y, ALU_SRC_PV,_x),
|
||||
ALU_MULADD(_R1,_z, _R1,_x, KC0(0),_z, ALU_SRC_PV,_w),
|
||||
ALU_MULADD(_R1,_w, _R1,_x, KC0(0),_w, ALU_SRC_PV,_z)
|
||||
ALU_LAST,
|
||||
}
|
||||
};
|
||||
|
||||
__attribute__((aligned(GX2_SHADER_ALIGNMENT)))
|
||||
static struct
|
||||
{
|
||||
u64 cf[16];
|
||||
u64 tex[1 * 2];
|
||||
}
|
||||
ps_program =
|
||||
{
|
||||
{
|
||||
TEX(16, 1) VALID_PIX,
|
||||
EXP_DONE(PIX0, _R0, _x, _y, _z, _w)
|
||||
END_OF_PROGRAM
|
||||
},
|
||||
{
|
||||
TEX_SAMPLE(_R0,_x,_y,_z,_w, _R0,_x,_y,_0,_0, _t0, _s0)
|
||||
}
|
||||
};
|
||||
|
||||
static GX2AttribVar attributes[] =
|
||||
{
|
||||
{ "Position", GX2_SHADER_VAR_TYPE_FLOAT4, 0, 0},
|
||||
{ "TexCoord", GX2_SHADER_VAR_TYPE_FLOAT2, 0, 1},
|
||||
};
|
||||
|
||||
static GX2AttribStream attribute_stream[] =
|
||||
{
|
||||
{0, 0, offsetof(frame_vertex_t, pos), GX2_ATTRIB_FORMAT_FLOAT_32_32,
|
||||
GX2_ATTRIB_INDEX_PER_VERTEX, 0, GX2_COMP_SEL(_x, _y, _0, _1), GX2_ENDIAN_SWAP_DEFAULT},
|
||||
{1, 0, offsetof(frame_vertex_t, coord), GX2_ATTRIB_FORMAT_FLOAT_32_32,
|
||||
GX2_ATTRIB_INDEX_PER_VERTEX, 0, GX2_COMP_SEL(_x, _y, _0, _0), GX2_ENDIAN_SWAP_DEFAULT},
|
||||
};
|
||||
|
||||
static GX2SamplerVar samplers[] =
|
||||
{
|
||||
{ "Source", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, 0 },
|
||||
};
|
||||
|
||||
static GX2UniformBlock uniform_blocks[] = {
|
||||
{"UBO", 1, 64}
|
||||
};
|
||||
|
||||
static GX2UniformVar uniform_vars[] = {
|
||||
{"global.MVP", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, 0, 0},
|
||||
};
|
||||
|
||||
|
||||
GX2Shader frame_shader =
|
||||
{
|
||||
{
|
||||
{
|
||||
.sq_pgm_resources_vs.num_gprs = 3,
|
||||
.sq_pgm_resources_vs.stack_size = 1,
|
||||
.spi_vs_out_config.vs_export_count = 0,
|
||||
.num_spi_vs_out_id = 1,
|
||||
{
|
||||
{.semantic_0 = 0x00, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
{.semantic_0 = 0xFF, .semantic_1 = 0xFF, .semantic_2 = 0xFF, .semantic_3 = 0xFF},
|
||||
},
|
||||
.sq_vtx_semantic_clear = ~0x3,
|
||||
.num_sq_vtx_semantic = 2,
|
||||
{
|
||||
0, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
},
|
||||
.vgt_vertex_reuse_block_cntl.vtx_reuse_depth = 0xE,
|
||||
.vgt_hos_reuse_depth.reuse_depth = 0x10,
|
||||
}, /* regs */
|
||||
.size = sizeof(vs_program),
|
||||
.program = (uint8_t*)&vs_program,
|
||||
.mode = GX2_SHADER_MODE_UNIFORM_BLOCK,
|
||||
.uniformBlockCount = countof(uniform_blocks), uniform_blocks,
|
||||
.uniformVarCount = countof(uniform_vars), uniform_vars,
|
||||
.attribVarCount = countof(attributes), attributes,
|
||||
},
|
||||
{
|
||||
{
|
||||
.sq_pgm_resources_ps.num_gprs = 1,
|
||||
.sq_pgm_exports_ps.export_mode = 0x2,
|
||||
.spi_ps_in_control_0.num_interp = 1,
|
||||
.spi_ps_in_control_0.persp_gradient_ena = 1,
|
||||
.spi_ps_in_control_0.baryc_sample_cntl = spi_baryc_cntl_centers_only,
|
||||
.num_spi_ps_input_cntl = 1, {{.semantic = 0, .default_val = 1}},
|
||||
.cb_shader_mask.output0_enable = 0xF,
|
||||
.cb_shader_control.rt0_enable = TRUE,
|
||||
.db_shader_control.z_order = db_z_order_early_z_then_late_z,
|
||||
}, /* regs */
|
||||
.size = sizeof(ps_program),
|
||||
.program = (uint8_t*)&ps_program,
|
||||
.mode = GX2_SHADER_MODE_UNIFORM_BLOCK,
|
||||
.samplerVarCount = countof(samplers), samplers,
|
||||
},
|
||||
.attribute_stream = attribute_stream,
|
||||
};
|
46
wiiu/frame_shader.h
Normal file
46
wiiu/frame_shader.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2018 - 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __FRAME_SHADER_H_
|
||||
#define __FRAME_SHADER_H_
|
||||
|
||||
#include <wiiu/shader_utils.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
}pos;
|
||||
|
||||
struct
|
||||
{
|
||||
float u;
|
||||
float v;
|
||||
}coord;
|
||||
}frame_vertex_t;
|
||||
|
||||
extern GX2Shader frame_shader;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FRAME_SHADER_H_
|
@ -81,9 +81,9 @@
|
||||
to_LE(src0Abs | (src1Abs << 1) | (updateExecuteMask << 2) | (updatePred << 3) | (writeMask << 4) | (omod << 5) | (inst << 7) | \
|
||||
(encoding << 15) | (bankSwizzle << 18) | ((dstGpr&0x7F) << 21) | (dstRel << 28) | ((dstChan&0x3) << 29) | (clamp << 31))
|
||||
|
||||
#define ALU_WORD1_OP3(src2Sel, src2Rel, src2Chan, src2Neg, inst, encoding, bankSwizzle, dstGpr, dstRel, dstChan, clamp) \
|
||||
#define ALU_WORD1_OP3(src2Sel, src2Rel, src2Chan, src2Neg, inst, bankSwizzle, dstGpr, dstRel, dstChan, clamp) \
|
||||
to_LE(src2Sel | (src2Rel << 9) | (src2Chan << 10) | (src2Neg << 12) | (inst << 13) | \
|
||||
(encoding << 15) | (bankSwizzle << 18) | ((dstGpr&0x7F) << 21) | (dstRel << 28) | ((dstChan&0x3) << 29) | (clamp << 31)
|
||||
(bankSwizzle << 18) | ((dstGpr&0x7F) << 21) | (dstRel << 28) | ((dstChan&0x3) << 29) | (clamp << 31))
|
||||
|
||||
/* TEX */
|
||||
#define TEX_WORD0(inst, bcFracMode, fetchWholeQuad, resourceID, srcReg, srcRel, altConst) \
|
||||
@ -200,6 +200,8 @@
|
||||
#define OP2_INST_MUL_IEEE 0x2
|
||||
#define OP2_INST_MOV 0x19
|
||||
#define OP2_INST_RECIP_IEEE 0x66
|
||||
|
||||
#define OP3_INST_MULADD 0x10
|
||||
/* EXP */
|
||||
#define CF_INST_EXP 0x27
|
||||
#define CF_INST_EXP_DONE 0x28
|
||||
@ -292,6 +294,10 @@
|
||||
to_QWORD(ALU_WORD0(src0Sel, 0x0, src0Chan, 0x0, src1Sel, 0x0, src1Chan, 0x0, 0x0, 0x0), \
|
||||
ALU_WORD1_OP2(0x0, 0x0, 0x0, 0x0, (((dstGpr&__) >> 7) ^ 0x1), omod, inst, 0x0, 0x0, dstGpr, 0x0, dstChan, 0x0))
|
||||
|
||||
#define ALU_OP3(inst, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) \
|
||||
to_QWORD(ALU_WORD0(src0Sel, 0x0, src0Chan, 0x0, src1Sel, 0x0, src1Chan, 0x0, 0x0, 0x0), \
|
||||
ALU_WORD1_OP3(src2Sel, 0x0, src2Chan, 0x0, inst, 0x0, dstGpr, 0x0, dstChan, 0x0))
|
||||
|
||||
#define ALU_MOV(dstGpr, dstChan, src0Sel, src0Chan) \
|
||||
ALU_OP2(OP2_INST_MOV, dstGpr, dstChan, src0Sel, src0Chan, ALU_SRC_0, 0x0, ALU_OMOD_OFF)
|
||||
|
||||
@ -301,6 +307,9 @@
|
||||
#define ALU_MUL(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \
|
||||
ALU_OP2(OP2_INST_MUL, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF)
|
||||
|
||||
#define ALU_MULADD(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan) \
|
||||
ALU_OP3(OP3_INST_MULADD, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, src2Sel, src2Chan)
|
||||
|
||||
#define ALU_MUL_IEEE(dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan) \
|
||||
ALU_OP2(OP2_INST_MUL_IEEE, dstGpr, dstChan, src0Sel, src0Chan, src1Sel, src1Chan, ALU_OMOD_OFF)
|
||||
|
||||
|
@ -45,6 +45,22 @@ __attribute__((scalar_storage_order ("little-endian")))
|
||||
};
|
||||
}GX2_vec4;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GX2_vec4 v0;
|
||||
GX2_vec4 v1;
|
||||
GX2_vec4 v2;
|
||||
GX2_vec4 v3;
|
||||
};
|
||||
struct __attribute__((scalar_storage_order ("little-endian")))
|
||||
{
|
||||
float data[16];
|
||||
};
|
||||
}GX2_mat4x4;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GX2VertexShader vs;
|
||||
|
@ -217,14 +217,14 @@ static GX2SamplerVar samplers[] =
|
||||
{ "s", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, 0 },
|
||||
};
|
||||
|
||||
GX2UniformBlock uniform_blocks[] =
|
||||
static GX2UniformBlock uniform_blocks[] =
|
||||
{
|
||||
{"UBO_vp", 1, sizeof(GX2_vec2)},
|
||||
{"UBO_tex", 2, sizeof(GX2_vec2)},
|
||||
};
|
||||
|
||||
|
||||
GX2UniformVar uniform_vars[] =
|
||||
static GX2UniformVar uniform_vars[] =
|
||||
{
|
||||
{"vp_size", GX2_SHADER_VAR_TYPE_FLOAT2, 1, 0, 0},
|
||||
{"tex_size", GX2_SHADER_VAR_TYPE_FLOAT2, 1, 0, 1},
|
||||
|
Loading…
x
Reference in New Issue
Block a user