PowerVR Framework: Getting started with the PVRApi Vulkan and OpenGL ES abstraction

In this blog series we’re going to explain how to create cross-platform, cross-API graphics applications using the PowerVR Framework – all from one set of source code files!

The series will be split into the following parts:

  • PowerVR Framework: Getting started with the PVRApi Vulkan and OpenGL ES abstraction
  • PowerVR Framework: Writing portable Vulkan and OpenGL ES 3.0/3.1 apps with PVRApi
  • PowerVR Framework: Loading scenes, textures and shaders with PVRAssets
  • PowerVR Framework: Understanding image barriers for render to texture effects

Let’s get started with part one!

The aim of part one is the cleared screen below:

Intro1ClearApi

Whilst not the most advanced example, it introduces the first concepts required to write a framework application.

First, let’s talk a bit about the motivation and aim of the PowerVR framework and why you would want to use it.

The new framework is designed to:

  • Support new explicit APIs such as Vulkan – exposing their power whilst hiding their verbosity
  • Continue to support OpenGL ES 3.x – allowing use of fast paths that mimic explicit APIs where possible
  • Support all major platforms with one source base – Android, iOS, Windows, Linux and OS X

Most of all, the framework should allow us to focus on high level design removing as much boiler plate code as possible

Please see An overview of the new PowerVR Framework for more information and Learn more about the Vulkan API if unfamiliar with Vulkan.

Now we’re going to create the first example – Intro1ClearApi.

To build it, you will require git, CMake 3.1+ and a supported IDE/platform.

The following platforms have been tested using CMake 3.3.1 and where applicable PVRVFrame libraries from the SDK 16.1 release were used:

  • Visual Studio 14
  • XCode – iOS and OS X
  • Android Ninja and Visual Studio 14
  • Ubuntu 14.04 Make

All examples and CMake files are hosted on GitHub in the following repository:

PVRApiIntro

Please see the GitHub page for how to build and run Intro1ClearApi for supported platforms. Detailed instructions are provided on the page describing the CMake build process. The CMake files are a great base for your own Framework based projects. If you have any problems building the examples please contact us on PowerVR Support or on the PowerVR Forum.

Let’s go over the first concepts of writing an application for the framework by going through Intro1ClearApi. All the source code is contained in ClearAPI.cpp.

To write an application which targets the framework we extend pvr::Shell and implement the following entry points –

class MyApp : public pvr
{
public:

     virtual pvr::Result::Enum initApplication(); // Perform non-graphics set-up - audio initialization etc
     virtual pvr::Result::Enum initView(); // Graphics set-up - load textures, create command buffers etc
     virtual pvr::Result::Enum renderFrame(); // Render frame called at VSync rate - submit command buffers etc
     virtual pvr::Result::Enum releaseView(); // Graphics tear down - delete textures, command buffers etc
     virtual pvr::Result::Enum quitApplication(); // Non-graphics tear down - close audio devices etc
};

initApplication() and quitApplication() – For Intro1ClearAPI we return pvr::Result::Success in both. There is no non-graphics set-up to be done. initView() – This forms the core of Intro1ClearAPI. In modern APIs such as Vulkan we want to create CommandBuffers outside of our main rendering thread (renderFrame() function). We can use a second thread to do this or with static requirements on CommandBuffers we can do this entirely in initView(). For Intro1ClearAPI we prepare all CommandBuffers in initView() creating one for each frame buffer in the swap chain. We submit these CommandBuffers in renderFrame().

pvr::Result::Enum OGLESIntroducingPVRApi::initView() {
    onscreenFB = getGraphicsContext()->createOnScreenFboSet(); // This returns an array of our on-screen frame buffers. In OpenGL ES we just receive one.
    // We then create a command buffer for each frame buffer
    for (int i = 0 ; i < getSwapChainLength(); i++){
        onscreenCBArray.add(getGraphicsContext()->createCommandBufferOnDefaultPool());
    auto & cb = onscreenCBArray[i];
    auto & frameBuffer = onscreenFB[i];
    // We record a command buffer with a render pass that clears the screen for each frame buffer
    cb->beginRecording();
    cb->beginRenderPass(frameBuffer, pvr::Rectanglei(0, 0, getWidth(), getHeight()),false,
    glm::vec4(123.0 / 255.0, 172.0 / 255.0, 189.0 / 255.0, 1.0));
    cb->endRenderPass();
    cb->endRecording();
    }
return pvr::Result::Success;
};

renderFrame() – At this point we have our CommandBuffers created for each frame buffer by initView(). renderFrame() is called after initView() at VSync rate to … render our frame. By calling getSwapChainIndex() we can determine which frame buffer is next in the swap chain. We then submit the corresponding CommandBuffer for the frame buffer – rendering our frame to the screen.

pvr::Result::Enum OGLESIntroducingPVRApi::renderFrame(){

    onscreenCBArray[getSwapChainIndex()]->submit();

    return pvr::Result::Success;

}

The submission of CommandBuffers has a very low cost in Vulkan – by only submitting CommmandBuffers on the rendering thread we ensure a stable frame rate. If a new CommandBuffer is required we should create this in a background thread – taking advantage of modern multi-core processors.

releaseView() – This is the last function to cover and we again return pvr::Result::Success.

In this introduction we have gone over the simplest principles required to render to the screen using the PowerVR Framework.

Compared to raw Vulkan calls, the reduction in verbosity is considerable. For comparison, here is the API stream – including structure parameters – generated by the PowerVR Framework to render this basic scene Intro1ClearApi Vulkan API calls.

The framework also simplifiers OpenGL ES rendering by abstracting all EGL/window set-up Intro1ClearApi OpenGL ES calls.

Importantly this same code covers all platforms – both OpenGL ES and Vulkan, providing an abstraction that works for both APIs.

In the next part we go through the process of drawing a triangle which exposes the first differences between Vulkan and OpenGL ES when using PVRApi.

See you there!

 

  • Search by Tag

    Search for posts by tag.

    Search by Author

    Search for posts by one of our authors.

    Featured posts
    Popular posts

    Blog Contact

    If you have any enquiries regarding any of our blog posts, please contact:

    United Kingdom

    benny.har-even@imgtec.com
    Tel: +44 (0)1923 260 511

    Related blog articles

    British Engineering Excellence Award

    PowerVR Vision & AI design team collect another award

    We’re delighted that the design team for our PowerVR Series2NX Neural Network Accelerator (NNA) has been honoured with a prestigious British Engineering Excellence Award (BEEA). The BEEAs were established in 2009 to demonstrate the high calibre of engineering design and innovation in the

    Series8XT AR/VR Banner

    Imagination Technologies: the ray tracing pioneers

    After a period out of the spotlight, ray tracing technology has recently come back into focus, taking up a lot of column inches in the tech press. The primary reason is because graphics cards for the PC gaming market have

    Amazon Fire Stick 4K pic

    Amazon Lights up its Fire TV Stick 4K with PowerVR

    Amazon, the internet shopping giant, announced earlier this week the latest version of its media streaming device, the Fire TV Stick 4K. First released in 2016, the Fire TV stick brings catch-up streaming services to any TV with an HDMI

    Stay up-to-date with Imagination

    Sign up to receive the latest news and product updates from Imagination straight to your inbox.

    • This field is for validation purposes and should be left unchanged.
    >
    Contact Us

    Contact Us