diff --git a/Makefile.wiiu b/Makefile.wiiu index c8babcf725..52dfc4a6d9 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -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 diff --git a/gfx/common/gx2_common.h b/gfx/common/gx2_common.h index 9402d72a2a..036084b348 100644 --- a/gfx/common/gx2_common.h +++ b/gfx/common/gx2_common.h @@ -1,6 +1,6 @@ #include -#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; diff --git a/gfx/drivers/wiiu_gfx.c b/gfx/drivers/wiiu_gfx.c index 6946e5f2dc..cc1c22105a 100644 --- a/gfx/drivers/wiiu_gfx.c +++ b/gfx/drivers/wiiu_gfx.c @@ -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; } } diff --git a/menu/drivers_display/menu_display_wiiu.c b/menu/drivers_display/menu_display_wiiu.c index 6fd911e50a..514ce091f0 100644 --- a/menu/drivers_display/menu_display_wiiu.c +++ b/menu/drivers_display/menu_display_wiiu.c @@ -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); diff --git a/wiiu/frame_shader.c b/wiiu/frame_shader.c new file mode 100644 index 0000000000..a442238b8f --- /dev/null +++ b/wiiu/frame_shader.c @@ -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 . + */ + +#include +#include +#include +#include +#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, +}; diff --git a/wiiu/frame_shader.h b/wiiu/frame_shader.h new file mode 100644 index 0000000000..ecea9a5679 --- /dev/null +++ b/wiiu/frame_shader.h @@ -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 . + */ + +#ifndef __FRAME_SHADER_H_ +#define __FRAME_SHADER_H_ + +#include + +#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_ diff --git a/wiiu/gx2_shader_inl.h b/wiiu/gx2_shader_inl.h index 857104bf5a..cf0a33bcab 100644 --- a/wiiu/gx2_shader_inl.h +++ b/wiiu/gx2_shader_inl.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) diff --git a/wiiu/shader_utils.h b/wiiu/shader_utils.h index 0840dad486..4ff1b2c100 100644 --- a/wiiu/shader_utils.h +++ b/wiiu/shader_utils.h @@ -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; diff --git a/wiiu/sprite_shader.c b/wiiu/sprite_shader.c index c1f0a82c9c..b300b62e70 100644 --- a/wiiu/sprite_shader.c +++ b/wiiu/sprite_shader.c @@ -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},