예제 #1
0
Shader3D::Shader3D()
    : vertexShader(cuAttributeCount)
{
    //! create pixel shader
    pixelShader.setProgram(cPixelShaderProgram, sizeof(cPixelShaderProgram), cPixelShaderRegs, sizeof(cPixelShaderRegs));

    colorIntensityLocation = 0;
    fadeDistanceLocation = 4;
    fadeOutLocation = 8;
    pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
    pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_distance", GX2_VAR_TYPE_FLOAT, 1, fadeDistanceLocation, 0xffffffff });
    pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_out_alpha", GX2_VAR_TYPE_VEC4, 1, fadeOutLocation, 0xffffffff });

    samplerLocation = 0;
    pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });

    //! create vertex shader
    vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));

    modelMatrixLocation = 0;
    projectionMatrixLocation = 16;
    viewMatrixLocation = 32;
    vertexShader.addUniformVar((GX2UniformVar){ "modelMatrix", GX2_VAR_TYPE_MAT4, 1, modelMatrixLocation, 0xffffffff });
    vertexShader.addUniformVar((GX2UniformVar){ "viewMatrix", GX2_VAR_TYPE_MAT4, 1, projectionMatrixLocation, 0xffffffff });
    vertexShader.addUniformVar((GX2UniformVar){ "projectionMatrix", GX2_VAR_TYPE_MAT4, 1, viewMatrixLocation, 0xffffffff });

    positionLocation = 0;
    texCoordLocation = 1;
    vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
    vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });

    //! setup attribute streams
    GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
    GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);

    //! create fetch shader
    fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());

    //! initialize default quad texture vertexes as those are very commonly used
    //! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
    posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
    texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);

    //! position vertex structure and texture coordinate vertex structure
    int i = 0;
    posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] =  1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] =  1.0f; posVtxs[i++] =  1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] = -1.0f; posVtxs[i++] =  1.0f; posVtxs[i++] = 0.0f;
    GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);

    i = 0;
    texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
    texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
    texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
    texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
    GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
}
예제 #2
0
GridBackground::GridBackground(GuiImageData *img)
    : GuiImage(img)
{
    colorIntensity = glm::vec4(1.0f, 1.0f, 1.0f, 0.9f);
    alphaFadeOut = glm::vec4(0.0f);
    distanceFadeOut = 0.15f;

    vtxCount = 4;

    //! texture and vertex coordinates
    f32 *m_posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuVertexAttrSize);
    f32 *m_texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuTexCoordAttrSize);

    if(m_posVtxs)
    {
        int i = 0;
        m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.0f;
        m_posVtxs[i++] =  1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.0f;
        m_posVtxs[i++] =  1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = -1.0f;
        m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = -1.0f;
        GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, m_posVtxs, vtxCount * Shader3D::cuVertexAttrSize);
    }

    if(m_texCoords)
    {
        glm::vec2 texCoordVec[4];
        texCoordVec[0][0] = -0.5f * bgRepeat; texCoordVec[0][1] = 0.5f * bgRepeat;
        texCoordVec[1][0] = 0.5f * bgRepeat; texCoordVec[1][1] = 0.5f * bgRepeat;
        texCoordVec[2][0] = 0.5f * bgRepeat; texCoordVec[2][1] = -0.5f * bgRepeat;
        texCoordVec[3][0] = -0.5f * bgRepeat; texCoordVec[3][1] = -0.5f * bgRepeat;

        const float cosRot = cosf(DegToRad(bgTexRotate));
        const float sinRot = sinf(DegToRad(bgTexRotate));

        glm::mat2 texRotateMtx({
            cosRot, -sinRot,
            sinRot, cosRot
        });

        for(int i = 0; i < 4; i++)  {
            texCoordVec[i] = texRotateMtx * texCoordVec[i];
            m_texCoords[i*2 + 0] = texCoordVec[i][0];
            m_texCoords[i*2 + 1] = texCoordVec[i][1];
        }

        GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, m_texCoords, vtxCount * Shader3D::cuTexCoordAttrSize);
    }

    //! assign to internal variables which are const but oh well
    posVtxs = m_posVtxs;
    texCoords = m_texCoords;
}
예제 #3
0
static void* wiiu_font_init_font(void* data, const char* font_path,
      float font_size, bool is_threaded)
{
   uint32_t i;
   wiiu_font_t* font = (wiiu_font_t*)calloc(1, sizeof(*font));

   if (!font)
      return NULL;

   if (!font_renderer_create_default(
            &font->font_driver,
            &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      free(font);
      return NULL;
   }

   font->atlas = font->font_driver->get_atlas(font->font_data);
   font->texture.surface.width       = font->atlas->width;
   font->texture.surface.height      = font->atlas->height;
   font->texture.surface.depth       = 1;
   font->texture.surface.dim         = GX2_SURFACE_DIM_TEXTURE_2D;
   font->texture.surface.tileMode    = GX2_TILE_MODE_LINEAR_ALIGNED;
   font->texture.viewNumSlices       = 1;

   font->texture.surface.format   = GX2_SURFACE_FORMAT_UNORM_R8;
   font->texture.compMap          = GX2_COMP_SEL(_R, _R, _R, _R);

   GX2CalcSurfaceSizeAndAlignment(&font->texture.surface);
   GX2InitTextureRegs(&font->texture);
   font->texture.surface.image = MEM1_alloc(font->texture.surface.imageSize,
                                 font->texture.surface.alignment);

   for (i = 0; (i < font->atlas->height) && (i < font->texture.surface.height); i++)
      memcpy((uint8_t*)font->texture.surface.image + (i * font->texture.surface.pitch),
             font->atlas->buffer + (i * font->atlas->width), font->atlas->width);

   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, font->texture.surface.image,
                 font->texture.surface.imageSize);

   font->atlas->dirty = false;

   font->ubo_tex = MEM1_alloc(sizeof(*font->ubo_tex), GX2_UNIFORM_BLOCK_ALIGNMENT);
   font->ubo_tex->width = font->texture.surface.width;
   font->ubo_tex->height = font->texture.surface.height;
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, font->ubo_tex,
                 sizeof(*font->ubo_tex));

   return font;
}
예제 #4
0
void GX2InitShader(GX2Shader *shader)
{
   if (shader->fs.program)
      return;

   shader->fs.size = GX2CalcFetchShaderSizeEx(shader->vs.attribVarCount,
                     GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
#ifdef GX2_CAN_ACCESS_DATA_SECTION
   shader->fs.program = MEM2_alloc(shader->fs.size, GX2_SHADER_ALIGNMENT);
#else
   shader->fs.program = MEM2_alloc(shader->fs.size + sizeof(org_programs_t), GX2_SHADER_ALIGNMENT);
#endif
   GX2InitFetchShaderEx(&shader->fs, (uint8_t *)shader->fs.program,
                        shader->vs.attribVarCount,
                        shader->attribute_stream,
                        GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, shader->fs.program, shader->fs.size);

#ifndef GX2_CAN_ACCESS_DATA_SECTION
   org_programs_t *org = (org_programs_t *)(shader->fs.program + shader->fs.size);
   org->vs_program = shader->vs.program;
   org->ps_program = shader->ps.program;
   org->gs_program = shader->gs.program;
   org->gs_copy_program = shader->gs.copyProgram;

   shader->vs.program = MEM2_alloc(shader->vs.size, GX2_SHADER_ALIGNMENT);
   memcpy(shader->vs.program, org->vs_program, shader->vs.size);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, shader->vs.program, shader->vs.size);

   shader->ps.program = MEM2_alloc(shader->ps.size, GX2_SHADER_ALIGNMENT);
   memcpy(shader->ps.program, org->ps_program, shader->ps.size);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, shader->ps.program, shader->ps.size);

   if (org->gs_program)
   {
      shader->gs.program = MEM2_alloc(shader->gs.size, GX2_SHADER_ALIGNMENT);
      memcpy(shader->gs.program, org->gs_program, shader->gs.size);
      GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, shader->gs.program, shader->gs.size);

      shader->gs.copyProgram = MEM2_alloc(shader->gs.copyProgramSize, GX2_SHADER_ALIGNMENT);
      memcpy(shader->gs.copyProgram, org->gs_copy_program, shader->gs.copyProgramSize);
      GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, shader->gs.copyProgram, shader->gs.copyProgramSize);
   }

#endif

}
예제 #5
0
FXAAShader::FXAAShader()
    : vertexShader(cuAttributeCount)
{
    //! create pixel shader
    pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));

    resolutionLocation = 0;
    pixelShader.addUniformVar((GX2UniformVar){ "unf_resolution", GX2_VAR_TYPE_VEC2, 1, resolutionLocation, 0xffffffff });

    samplerLocation = 0;
    pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });

    //! create vertex shader
    vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));

    positionLocation = 0;
    texCoordLocation = 1;
    vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
    vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });

    //! setup attribute streams
    GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
    GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);

    //! create fetch shader
    fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());

    //! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
    posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
    texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);

    //! position vertex structure and texture coordinate vertex structure
    int i = 0;
    posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] =  1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] =  1.0f; posVtxs[i++] =  1.0f; posVtxs[i++] = 0.0f;
    posVtxs[i++] = -1.0f; posVtxs[i++] =  1.0f; posVtxs[i++] = 0.0f;
    GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);

    i = 0;
    texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
    texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
    texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
    texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
    GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
}
예제 #6
0
void init_cursor(){
    if(!gCursorInitDone){
        if(!cursor_colorVtxs){
            cursor_colorVtxs = (u8*)memalign(0x40, sizeof(u8) * 16);
            if(cursor_colorVtxs == NULL) return;
        }
        memset(cursor_colorVtxs,0xFF,16*sizeof(u8));
        GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, cursor_colorVtxs, 16 * sizeof(u8));
        gCursorInitDone = 1;
    }
}
예제 #7
0
static wiiu_set_position(position_t* position, GX2ColorBuffer* draw_buffer, float x0, float y0, float x1, float y1)
{
   position[0].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;
   position[0].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
   position[1].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
   position[1].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
   position[2].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
   position[2].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
   position[3].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;;
   position[3].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, position, 4 * sizeof(*position));
}
예제 #8
0
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));
}
예제 #9
0
static void wiiu_gfx_set_texture_frame(void* data, const void* frame, bool rgb32,
                                   unsigned width, unsigned height, float alpha)
{
   int i;
   wiiu_video_t* wiiu = (wiiu_video_t*) data;

   if (!wiiu)
      return;

   if (!frame || !width || !height)
      return;

   if (width > wiiu->menu.texture.surface.width)
      width = wiiu->menu.texture.surface.width;

   if (height > wiiu->menu.texture.surface.height)
      height = wiiu->menu.texture.surface.height;

   wiiu->menu.width = width;
   wiiu->menu.height = height;

   const uint16_t* src = frame;
   uint16_t* dst = (uint16_t*)wiiu->menu.texture.surface.image;

   for (i = 0; i < height; i++)
   {
      memcpy(dst, src, width * sizeof(uint16_t));
      dst += wiiu->menu.texture.surface.pitch;
      src += width;
   }

   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);
}
예제 #10
0
static bool wiiu_gfx_frame(void* data, const void* frame,
                           unsigned width, unsigned height, uint64_t frame_count,
                           unsigned pitch, const char* msg)
{
   (void)msg;
   int i;

   wiiu_video_t* wiiu = (wiiu_video_t*) data;

   if (!width || !height)
   {
      GX2WaitForVsync();
      return true;
   }

   if(wiiu->vsync)
   {
      uint32_t swap_count;
      uint32_t flip_count;
      OSTime last_flip;
      OSTime last_vsync;

      GX2GetSwapStatus(&swap_count, &flip_count, &last_flip, &last_vsync);

      if(wiiu->last_vsync >= last_vsync)
      {
         GX2WaitForVsync();
         wiiu->last_vsync = last_vsync + ms_to_ticks(17);
      }
      else
         wiiu->last_vsync = last_vsync;
   }
   GX2WaitForFlip();

   static u32 lastTick , currentTick;
   currentTick = OSGetSystemTick();
   u32 diff = currentTick - lastTick;
   static float fps;
   static u32 frames;
   frames++;
   if(diff > wiiu_timer_clock)
   {
      fps = (float)frames * ((float) wiiu_timer_clock / (float) diff);
      lastTick = currentTick;
      frames = 0;
   }
#if 0
   static u32 last_frame_tick;
   if (!(wiiu->menu.enable))
      printf("\r frame time : %10.6f ms            \n", (float)(currentTick - last_frame_tick) * 1000.0f / (float)wiiu_timer_clock);
   last_frame_tick = currentTick;
#endif
   printf("\rfps: %8.8f frames : %5i", fps, wiiu->frames++);
   fflush(stdout);

   static struct retro_perf_counter gfx_frame_perf = {0};
   performance_counter_init(&gfx_frame_perf, "gfx_frame");
   performance_counter_start(&gfx_frame_perf);

   if (wiiu->should_resize)
      wiiu_gfx_update_viewport(wiiu);

   GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
   /* can't call GX2ClearColor after GX2SetContextState for whatever reason */
   GX2SetContextState(wiiu->ctx_state);

   if(frame)
   {
      if (width > wiiu->texture.surface.width)
         width = wiiu->texture.surface.width;

      if (height > wiiu->texture.surface.height)
         height = wiiu->texture.surface.height;

      wiiu->width = width;
      wiiu->height = height;
      if(wiiu->rgb32)
      {
         const uint32_t* src = frame;
         uint32_t* dst = (uint32_t*)wiiu->texture.surface.image;

         for (i = 0; i < height; i++)
         {
            int j;
            for(j = 0; j < width; j++)
               dst[j] = src[j];
            dst += wiiu->texture.surface.pitch;
            src += pitch / 4;
         }
      }
      else
      {
         const uint16_t* src = frame;
         uint16_t* dst = (uint16_t*)wiiu->texture.surface.image;

         for (i = 0; i < height; i++)
         {
            int j;
            for(j = 0; j < width; j++)
               dst[j] = __builtin_bswap16(src[j]);
            dst += wiiu->texture.surface.pitch;
            src += pitch / 2;
         }
      }


      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);
   }

   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);

   GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
   GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest,
                      wiiu->shader->sampler.location);

   GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);

   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);

      GX2SetPixelTexture(&wiiu->menu.texture, wiiu->shader->sampler.location);
      GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);

      GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
      GX2DrawDone();
   }

   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);

   GX2SwapScanBuffers();
   GX2Flush();
   performance_counter_stop(&gfx_frame_perf);

   return true;
}
예제 #11
0
static void* wiiu_gfx_init(const video_info_t* video,
                           const input_driver_t** input, void** input_data)
{
   int i;
   *input = NULL;
   *input_data = NULL;

   wiiu_video_t* wiiu = calloc(1, sizeof(*wiiu));

   if (!wiiu)
      return NULL;

   void* wiiuinput   = NULL;
   if (input && input_data)
   {
      wiiuinput = input_wiiu.init();
      *input = wiiuinput ? &input_wiiu : NULL;
      *input_data = wiiuinput;
   }

   /* 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 1
   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);
#ifdef GX2_CAN_ACCESS_DATA_SECTION
   wiiu->shader = &tex_shader;
#else
   /* 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));

#endif
   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.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;
   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);

   memset(wiiu->menu.texture.surface.image, 0x0, 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);

   /* clear leftover image */
   GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);

   GX2SwapScanBuffers();
   GX2Flush();
   GX2WaitForVsync();

   GX2SetTVEnable(GX2_ENABLE);
   GX2SetDRCEnable(GX2_ENABLE);

   wiiu->keep_aspect   = true;
   wiiu->should_resize = true;
   wiiu->smooth        = video->smooth;
   wiiu->vsync         = video->vsync;
   GX2SetSwapInterval(!!video->vsync);

   wiiu->vp.x           = 0;
   wiiu->vp.y           = 0;
   wiiu->vp.width       = 854;
   wiiu->vp.height      = 480;
   wiiu->vp.full_width  = 854;
   wiiu->vp.full_height = 480;
   video_driver_set_size(&wiiu->vp.width, &wiiu->vp.height);

   float refresh_rate = 60.0f / 1.001f;
   driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate);

   return wiiu;
}
예제 #12
0
static void wiiu_font_render_line(
      video_frame_info_t *video_info,
      wiiu_font_t* font, const char* msg, unsigned msg_len,
      float scale, const unsigned int color, float pos_x,
      float pos_y, unsigned text_align)
{
   unsigned i;
   wiiu_video_t* wiiu = (wiiu_video_t*)video_info->userdata;
   unsigned width   = video_info->width;
   unsigned height  = video_info->height;
   int x            = roundf(pos_x * width);
   int y            = roundf((1.0 - pos_y) * height);

   if(  !wiiu ||
         wiiu->vertex_cache.current + (msg_len * 4) > wiiu->vertex_cache.size)
      return;

   switch (text_align)
   {
      case TEXT_ALIGN_RIGHT:
         x -= wiiu_font_get_message_width(font, msg, msg_len, scale);
         break;

      case TEXT_ALIGN_CENTER:
         x -= wiiu_font_get_message_width(font, msg, msg_len, scale) / 2;
         break;
   }

   sprite_vertex_t* v = wiiu->vertex_cache.v + wiiu->vertex_cache.current;

   for (i = 0; i < msg_len; i++)
   {
      const char* msg_tmp            = &msg[i];
      unsigned code                  = utf8_walk(&msg_tmp);
      unsigned skip                  = msg_tmp - &msg[i];

      if (skip > 1)
         i += skip - 1;

      const struct font_glyph* glyph =
         font->font_driver->get_glyph(font->font_data, code);

      if (!glyph) /* Do something smarter here ... */
         glyph = font->font_driver->get_glyph(font->font_data, '?');

      if (!glyph)
         continue;

      v->pos.x = x + glyph->draw_offset_x * scale;
      v->pos.y = y + glyph->draw_offset_y * scale;
      v->pos.width = glyph->width * scale;
      v->pos.height = glyph->height * scale;

      v->coord.u = glyph->atlas_offset_x;
      v->coord.v = glyph->atlas_offset_y;
      v->coord.width = glyph->width;
      v->coord.height = glyph->height;

      v->color = color;

      v++;

      x += glyph->advance_x * scale;
      y += glyph->advance_y * scale;
   }

   int count = v - wiiu->vertex_cache.v - wiiu->vertex_cache.current;

   if (!count)
      return;

   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->vertex_cache.v + wiiu->vertex_cache.current, count * sizeof(wiiu->vertex_cache.v));

   if(font->atlas->dirty)
   {
      for (i = 0; (i < font->atlas->height) && (i < font->texture.surface.height); i++)
         memcpy(font->texture.surface.image + (i * font->texture.surface.pitch),
                font->atlas->buffer + (i * font->atlas->width), font->atlas->width);

      GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, font->texture.surface.image,
                    font->texture.surface.imageSize);
      font->atlas->dirty = false;
   }

   GX2SetPixelTexture(&font->texture, sprite_shader.ps.samplerVars[0].location);
   GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size, font->ubo_tex);

   GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, count, wiiu->vertex_cache.current, 1);

   GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size, wiiu->ubo_tex);

   wiiu->vertex_cache.current = v - wiiu->vertex_cache.v;
}
예제 #13
0
void
GX2InitFetchShaderEx(GX2FetchShader *fetchShader,
                     uint8_t *buffer,
                     uint32_t attribCount,
                     GX2AttribStream *attribs,
                     GX2FetchShaderType type,
                     GX2TessellationMode tessMode)
{
   if (type != GX2FetchShaderType::NoTessellation) {
      decaf_abort(fmt::format("Invalid GX2FetchShaderType {}", enumAsString(type)));
   }

   if (tessMode != GX2TessellationMode::Discrete) {
      decaf_abort(fmt::format("Invalid GX2TessellationMode {}", enumAsString(tessMode)));
   }

   auto someTessVar1 = 128u;
   auto someTessVar2 = 128u;
   auto numGPRs = 0u;
   auto barrier = false;

   // Calculate instruction pointers
   auto fetchCount = GX2FSCalcNumFetchInsts(attribCount, type);
   auto aluCount = 0; // GX2FSCalcNumAluInsts(type, tessMode);
   auto cfCount = GX2FSCalcNumCFInsts(fetchCount, type);

   auto fetchSize = fetchCount * sizeof(latte::VertexFetchInst);
   auto cfSize = cfCount * sizeof(latte::ControlFlowInst);
   auto aluSize = aluCount * sizeof(latte::AluInst);

   auto cfOffset = 0u;
   auto aluOffset = cfSize;
   auto fetchOffset = align_up(cfSize + aluSize, 0x10u);

   auto cfPtr = reinterpret_cast<latte::ControlFlowInst *>(buffer + cfOffset);
   auto aluPtr = reinterpret_cast<latte::AluInst *>(buffer + aluOffset);
   auto fetchPtr = reinterpret_cast<latte::VertexFetchInst *>(buffer + fetchOffset);

   // Setup fetch shader
   fetchShader->type = type;
   fetchShader->attribCount = attribCount;
   fetchShader->data = buffer;
   fetchShader->size = GX2CalcFetchShaderSizeEx(attribCount, type, tessMode);

   // Generate fetch instructions
   auto indexMap = GX2FSGetIndexGprMap(type, tessMode);

   for (auto i = 0u; i < attribCount; ++i) {
      latte::VertexFetchInst vfetch;
      auto &attrib = attribs[i];
      std::memset(&vfetch, 0, sizeof(vfetch));

      if (attrib.buffer == 16) {
         // TODO: Figure out what these vars are for
         if (attrib.offset) {
            if (attrib.offset == 1) {
               someTessVar1 = attrib.location;
            }
         } else {
            someTessVar2 = attrib.location;
         }
      } else {
         // Semantic vertex fetch
         vfetch.word0 = vfetch.word0
            .VTX_INST(latte::SQ_VTX_INST_SEMANTIC)
            .BUFFER_ID(latte::SQ_RES_OFFSET::VS_ATTRIB_RESOURCE_0 + attrib.buffer - latte::SQ_RES_OFFSET::VS_TEX_RESOURCE_0);

         vfetch.word2 = vfetch.word2
            .OFFSET(attribs[i].offset);

         if (attrib.type) {
            auto selX = latte::SQ_SEL::SEL_X;
            auto fetchType = latte::SQ_VTX_FETCH_TYPE::VERTEX_DATA;

            if (attrib.type == GX2AttribIndexType::PerInstance) {
               if (attrib.aluDivisor == 1) {
                  fetchType = latte::SQ_VTX_FETCH_TYPE::INSTANCE_DATA;
                  selX = latte::SQ_SEL::SEL_W;
               } else if (attrib.aluDivisor == fetchShader->divisors[0]) {
                  fetchType = latte::SQ_VTX_FETCH_TYPE::INSTANCE_DATA;
                  selX = latte::SQ_SEL::SEL_Y;
               } else if (attrib.aluDivisor == fetchShader->divisors[1]) {
                  fetchType = latte::SQ_VTX_FETCH_TYPE::INSTANCE_DATA;
                  selX = latte::SQ_SEL::SEL_Z;
               } else {
                  fetchShader->divisors[fetchShader->numDivisors] = attrib.aluDivisor;

                  if (fetchShader->numDivisors == 0) {
                     selX = latte::SQ_SEL::SEL_Y;
                  } else if (fetchShader->numDivisors == 1) {
                     selX = latte::SQ_SEL::SEL_Z;
                  }

                  fetchShader->numDivisors++;
               }
            }

            vfetch.word0 = vfetch.word0
               .FETCH_TYPE(fetchType)
               .SRC_SEL_X(selX);
         } else {
            vfetch.word0 = vfetch.word0
               .SRC_GPR(indexMap[0].gpr)
               .SRC_SEL_X(static_cast<latte::SQ_SEL>(indexMap[0].chan));
         }

         // Setup dest
         vfetch.gpr = vfetch.gpr
            .DST_GPR(attrib.location);

         vfetch.word1 = vfetch.word1
            .DST_SEL_W(static_cast<latte::SQ_SEL>(attrib.mask & 0x7))
            .DST_SEL_Z(static_cast<latte::SQ_SEL>((attrib.mask >> 8) & 0x7))
            .DST_SEL_Y(static_cast<latte::SQ_SEL>((attrib.mask >> 16) & 0x7))
            .DST_SEL_X(static_cast<latte::SQ_SEL>((attrib.mask >> 24) & 0x7));

         // Setup mega fetch
         vfetch.word2 = vfetch.word2
            .MEGA_FETCH(1);

         vfetch.word0 = vfetch.word0
            .MEGA_FETCH_COUNT(internal::getAttribFormatBytes(attrib.format) - 1);

         // Setup format
         auto dataFormat = internal::getAttribFormatDataFormat(attrib.format);
         auto numFormat = latte::SQ_NUM_FORMAT::NORM;
         auto formatComp = latte::SQ_FORMAT_COMP::UNSIGNED;

         if (attribs[i].format & GX2AttribFormatFlags::SCALED) {
            numFormat = latte::SQ_NUM_FORMAT::SCALED;
         } else if (attribs[i].format & GX2AttribFormatFlags::INTEGER) {
            numFormat = latte::SQ_NUM_FORMAT::INT;
         }

         if (attribs[i].format & GX2AttribFormatFlags::SIGNED) {
            formatComp = latte::SQ_FORMAT_COMP::SIGNED;
         }

         vfetch.word1 = vfetch.word1
            .DATA_FORMAT(dataFormat)
            .NUM_FORMAT_ALL(numFormat)
            .FORMAT_COMP_ALL(formatComp);

         auto swapMode = internal::getSwapModeEndian(attribs[i].endianSwap & 3);

         if (attribs[i].endianSwap == latte::SQ_ENDIAN::AUTO) {
            swapMode = internal::getAttribFormatEndian(attribs[i].format);
         }

         vfetch.word2 = vfetch.word2
            .ENDIAN_SWAP(swapMode);

         // Append to program
         *(fetchPtr++) = vfetch;

         // Add extra tesselation vertex fetches
         if (type != GX2FetchShaderType::NoTessellation && attrib.type != GX2AttribIndexType::PerInstance) {
            auto perAttrib = GX2FetchInstsPerAttrib(type);

            for (auto j = 1u; j < perAttrib; ++j) {
               latte::VertexFetchInst vfetch2 = vfetch;

               // Update src/dst
               vfetch2.word0 = vfetch2.word0
                  .SRC_GPR(indexMap[j].gpr)
                  .SRC_SEL_X(static_cast<latte::SQ_SEL>(indexMap[j].chan));

               vfetch2.gpr = vfetch2.gpr
                  .DST_GPR(j + attrib.location);

               // Append to program
               *(fetchPtr++) = vfetch;
            }
         }
      }
   }

   // Generate tessellation ALU ops
   if (type != GX2FetchShaderType::NoTessellation) {
      numGPRs = 2;

      if (tessMode == GX2TessellationMode::Adaptive) {
         switch (type) {
         case GX2FetchShaderType::LineTessellation:
            numGPRs = 3;
            break;
         case GX2FetchShaderType::TriangleTessellation:
            numGPRs = 7;
            break;
         case GX2FetchShaderType::QuadTessellation:
            numGPRs = 7;
            break;
         }
      }

      // TODO: GX2FSGenTessAluOps
      barrier = true;
   }

   // Generate a VTX CF per 16 VFETCH
   if (fetchCount) {
      for (auto i = 0u; i < cfCount - 1; ++i) {
         auto fetches = FetchesPerControlFlow;

         if (fetchCount < (i + 1) * FetchesPerControlFlow) {
            // Don't overrun our fetches!
            fetches = fetchCount % FetchesPerControlFlow;
         }

         latte::ControlFlowInst inst;
         std::memset(&inst, 0, sizeof(inst));
         inst.word0.ADDR = static_cast<uint32_t>((fetchOffset + sizeof(latte::VertexFetchInst) * i * FetchesPerControlFlow) / 8);
         inst.word1 = inst.word1
            .COUNT((fetches - 1) & 0x7)
            .COUNT_3(((fetches - 1) >> 3) & 0x1)
            .CF_INST(latte::SQ_CF_INST_VTX_TC)
            .BARRIER(barrier ? 1 : 0);
         *(cfPtr++) = inst;
      }
   }

   // Generate tessellation "post" ALU ops
   if (numGPRs) {
      // TODO: GX2FSGenPostAluOps
   }

   // Generate an EOP
   latte::ControlFlowInst eop;
   std::memset(&eop, 0, sizeof(eop));
   eop.word1 = eop.word1
      .BARRIER(1)
      .CF_INST(latte::SQ_CF_INST_RETURN);
   *(cfPtr++) = eop;

   // Set sq_pgm_resources_fs
   auto sq_pgm_resources_fs = fetchShader->regs.sq_pgm_resources_fs.value();
   sq_pgm_resources_fs = sq_pgm_resources_fs
      .NUM_GPRS(numGPRs);
   fetchShader->regs.sq_pgm_resources_fs = sq_pgm_resources_fs;

   GX2Invalidate(GX2InvalidateMode::CPU, fetchShader->data, fetchShader->size);
}
예제 #14
0
void myGXthread(int argc, int *argv)
{
	if(argc != 2) OSFatal("GX Thread did not start proper!");
	unsigned int *tv_fb = (unsigned int*)argv[0];
	unsigned int *drc_fb = (unsigned int*)argv[1];
	unsigned int coreinit_handle, gx2_handle;
	OSDynLoad_Acquire("coreinit", &coreinit_handle);
	OSDynLoad_Acquire("gx2", &gx2_handle);

	void(*GX2Init)(void *args);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init);
	GX2Init((void*)0);

	int(*OSGetCoreId)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId);
	void(*GX2SwapScanBuffers)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	void(*GX2Shutdown)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
	int(*GX2GetMainCoreId)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId);
	if(OSGetCoreId() != GX2GetMainCoreId()) OSFatal("GX Not switched!");

	void(*GX2DrawDone)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawDone", &GX2DrawDone);
	void(*GX2Flush)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Flush", &GX2Flush);
	//void(*GX2SwapScanBuffers)();
	//OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	void(*GX2WaitForVsync)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2WaitForVsync", &GX2WaitForVsync);
	//Make sure buffer is usable for GX
	void(*GX2Invalidate)(unsigned int flags,void *buffer,unsigned int size);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Invalidate", &GX2Invalidate);
	GX2Invalidate(0x40,tv_fb,(1280*720*4)*2);
	GX2Invalidate(0x40,drc_fb,(854*480*4)*2);
	//set it!
	int(*GX2SetTVBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetTVBuffer", &GX2SetTVBuffer);
	int(*GX2SetDRCBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetDRCBuffer", &GX2SetDRCBuffer);
	GX2SetTVBuffer(tv_fb,(1280*720*4)*2,3,0x1A,2); //test gradient demo setup for show
	GX2SetDRCBuffer(drc_fb,(854*480*4)*2,1,0x1A,2); //will look broken, no color buffer setup yet
	/* Draw is far from complete */
	/*void(*GX2DrawEx)(int type, int count, int start, int instances);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawEx", &GX2DrawEx);
	void(*GX2SetAttribBuffer)(int index, int size, int vtxStride, void *buf);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetAttribBuffer", &GX2SetAttribBuffer);
	float myclearer[8] =
	{
		0.0f,  0.0f,
		1.0f,  0.0f,
		0.0f,  1.0f,
		1.0f,  1.0f
	};
	GX2Invalidate(0x40, myclearer, sizeof(myclearer));*/

	GX2ColorBuffer myCBuf;
	setupColorBuffer(&myCBuf, gx2_handle);

	void(*GX2ClearColor)(GX2ColorBuffer *buffer, float r, float g, float b, float a);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2ClearColor", &GX2ClearColor);

	void(*GX2SwapBuffers)(GX2ColorBuffer *buffer);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapBuffers", &GX2SwapBuffers);

	void(*GX2CopyColorBufferToScanBuffer)(GX2ColorBuffer *buffer, unsigned int target);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2CopyColorBufferToScanBuffer", &GX2CopyColorBufferToScanBuffer);

	float val = 1;
	float valInc = -0.005;
	val += valInc;
	while(val < 1)
	{
		val += valInc;
		//GX2SetAttribBuffer(0,sizeof(mybuf),8,mybuf);
		//GX2DrawEx(6,4,0,1);
		GX2ClearColor(&myCBuf, val, val, val, 1);
		GX2Invalidate(0x40, myCBuf.surface.imagePtr,myCBuf.surface.imageSize);
		GX2DrawDone();
		GX2Flush();
		GX2CopyColorBufferToScanBuffer(&myCBuf,1);
		GX2SwapScanBuffers();
		GX2Flush();
		GX2WaitForVsync();
		if(val <= 0) valInc = 0.005;
	}
	//clear for browser (needed?)
	GX2Shutdown();

	void(*_Exit)();
	OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
	_Exit();
}
예제 #15
0
GFDFile *gfd_open(const char *filename)
{
   GFDFile* gfd = calloc(1, sizeof(*gfd));
   FILE *fp = fopen(filename, "rb");

   if (!fp)
      goto error;

   fseek(fp, 0, SEEK_END);
   int size = ftell(fp);
   fseek(fp, 0, SEEK_SET);
   gfd->data = MEM2_alloc(size, GX2_SHADER_ALIGNMENT);
   fread(gfd->data, 1, size, fp);
   fclose(fp);

   GFDFileHeader *header = (GFDFileHeader *)gfd->data;

   if (header->magic != GFD_FILE_MAGIC)
   {
      printf("wrong file magic number.\n");
      goto error;
   }

   if (header->headerSize != sizeof(GFDFileHeader))
   {
      printf("wrong file header size.\n");
      goto error;
   }

   if (header->majorVersion != GFD_FILE_MAJOR_VERSION)
   {
      printf("file version not supported.\n");
      goto error;
   }

   if (header->gpuVersion != GFD_FILE_GPU_VERSION)
   {
      printf("gpu version not supported.\n");
      goto error;
   }

   if (!header->align)
   {
      printf("data is not aligned.\n");
      goto error;
   }

   GFDBlock *block = (GFDBlock *)(gfd->data + header->headerSize);

   while (block->header.type != GFD_BLOCK_TYPE_END_OF_FILE)
   {
      if (block->header.magic != GFD_BLOCK_MAGIC)
      {
         printf("wrong block magic number.\n");
         goto error;
      }

      if (block->header.headerSize != sizeof(GFDBlockHeader))
      {
         printf("wrong block header size.\n");
         goto error;
      }

      if (block->header.majorVersion != GFD_BLOCK_MAJOR_VERSION)
      {
         printf("block version not supported.\n");
         goto error;
      }

      switch (block->header.type)
      {
      case GFD_BLOCK_TYPE_VERTEX_SHADER_HEADER:
         if (gfd->vs)
            continue;

         gfd->vs = (GX2VertexShader*)block->data;
         if(!gfd_relocate_block(block))
            goto error;

         break;

      case GFD_BLOCK_TYPE_VERTEX_SHADER_PROGRAM:
         if(gfd->vs->program)
            continue;

         GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, block->data, block->header.dataSize);
         gfd->vs->program = block->data;
         break;

      case GFD_BLOCK_TYPE_PIXEL_SHADER_HEADER:
         if (gfd->ps)
            continue;

         gfd->ps = (GX2PixelShader*)block->data;
         if(!gfd_relocate_block(block))
            goto error;

         break;

      case GFD_BLOCK_TYPE_PIXEL_SHADER_PROGRAM:
         if(gfd->ps->program)
            continue;

         GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, block->data, block->header.dataSize);
         gfd->ps->program = block->data;
         break;

      default:
         break;
      }

      block = (GFDBlock *)((u8 *)block + block->header.headerSize + block->header.dataSize);
   }

   if(!gfd->vs)
   {
      printf("vertex shader is missing.\n");
      goto error;
   }

   if(!gfd->vs->program)
   {
      printf("vertex shader program is missing.\n");
      goto error;
   }

   if(!gfd->ps)
   {
      printf("pixel shader is missing.\n");
      goto error;
   }

   if(!gfd->ps->program)
   {
      printf("pixel shader program is missing.\n");
      goto error;
   }

   return gfd;

error:
   printf("failed to open file : %s\n", filename);
   gfd_free(gfd);

   return NULL;
}
예제 #16
0
static void wiiu_font_render_line(
      video_frame_info_t *video_info,
      wiiu_font_t* font, const char* msg, unsigned msg_len,
      float scale, const unsigned int color, float pos_x,
      float pos_y, unsigned text_align)
{
   unsigned i;
   wiiu_video_t* wiiu = (wiiu_video_t*)video_driver_get_ptr(false);
   unsigned width   = video_info->width;
   unsigned height  = video_info->height;
   int x            = roundf(pos_x * width);
   int y            = roundf((1.0f - pos_y) * height);
   int delta_x      = 0;
   int delta_y      = 0;

   if(wiiu->vertex_cache.current + (msg_len * 4) > wiiu->vertex_cache.size)
      return;

   switch (text_align)
   {
      case TEXT_ALIGN_RIGHT:
         x -= wiiu_font_get_message_width(font, msg, msg_len, scale);
         break;

      case TEXT_ALIGN_CENTER:
         x -= wiiu_font_get_message_width(font, msg, msg_len, scale) / 2;
         break;
   }

   position_t* pos = wiiu->vertex_cache.positions + wiiu->vertex_cache.current;
   tex_coord_t* coord = wiiu->vertex_cache.tex_coords + wiiu->vertex_cache.current;

   for (i = 0; i < msg_len; i++)
   {
      int off_x, off_y, tex_x, tex_y, width, height;
      const char* msg_tmp            = &msg[i];
      unsigned code                  = utf8_walk(&msg_tmp);
      unsigned skip                  = msg_tmp - &msg[i];

      if (skip > 1)
         i += skip - 1;

      const struct font_glyph* glyph =
         font->font_driver->get_glyph(font->font_data, code);

      if (!glyph) /* Do something smarter here ... */
         glyph = font->font_driver->get_glyph(font->font_data, '?');

      if (!glyph)
         continue;

      off_x  = glyph->draw_offset_x;
      off_y  = glyph->draw_offset_y;
      tex_x  = glyph->atlas_offset_x;
      tex_y  = glyph->atlas_offset_y;
      width  = glyph->width;
      height = glyph->height;


      float x0 = x + off_x + delta_x * scale;
      float y0 = y + off_y + delta_y * scale + height * scale;
      float u0 = tex_x;
      float v0 = tex_y;
      float x1 = x0 + width * scale;
      float y1 = y0 - height * scale;
      float u1 = u0 + width;
      float v1 = v0 + height;

      pos[0].x = (2.0f * x0 / wiiu->color_buffer.surface.width) - 1.0f;
      pos[0].y = (-2.0f * y0 / wiiu->color_buffer.surface.height) + 1.0f;
      pos[1].x = (2.0f * x1 / wiiu->color_buffer.surface.width) - 1.0f;;
      pos[1].y = (-2.0f * y0 / wiiu->color_buffer.surface.height) + 1.0f;
      pos[2].x = (2.0f * x1 / wiiu->color_buffer.surface.width) - 1.0f;;
      pos[2].y = (-2.0f * y1 / wiiu->color_buffer.surface.height) + 1.0f;
      pos[3].x = (2.0f * x0 / wiiu->color_buffer.surface.width) - 1.0f;;
      pos[3].y = (-2.0f * y1 / wiiu->color_buffer.surface.height) + 1.0f;
      pos += 4;

      coord[0].u = u0 / font->texture.surface.width;
      coord[0].v = v1 / font->texture.surface.height;
      coord[1].u = u1 / font->texture.surface.width;
      coord[1].v = v1 / font->texture.surface.height;
      coord[2].u = u1 / font->texture.surface.width;
      coord[2].v = v0 / font->texture.surface.height;
      coord[3].u = u0 / font->texture.surface.width;
      coord[3].v = v0 / font->texture.surface.height;
      coord += 4;

      delta_x += glyph->advance_x;
      delta_y += glyph->advance_y;
   }

   int count = pos - wiiu->vertex_cache.positions - wiiu->vertex_cache.current;

   if (!count)
      return;


   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->vertex_cache.positions + wiiu->vertex_cache.current, count * sizeof(position_t));
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->vertex_cache.tex_coords + wiiu->vertex_cache.current, count * sizeof(tex_coord_t));

   if(font->atlas->dirty)
   {
      for (i = 0; (i < font->atlas->height) && (i < font->texture.surface.height); i++)
         memcpy(font->texture.surface.image + (i * font->texture.surface.pitch),
                font->atlas->buffer + (i * font->atlas->width), font->atlas->width);

      GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, font->texture.surface.image,
                    font->texture.surface.imageSize);
      font->atlas->dirty = false;
   }


#if 0
   printf("%s\n", msg);
   DEBUG_VAR(color);
#endif

   GX2SetPixelTexture(&font->texture, wiiu->shader->sampler.location);

   GX2SetBlendConstantColor(((color >> 0) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f,
                            ((color >> 16) & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f);

   GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_BLEND_FACTOR, 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);

   GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, count, wiiu->vertex_cache.current, 1);

   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);

   wiiu->vertex_cache.current = pos - wiiu->vertex_cache.positions;
}