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!

 

1 thought on “PowerVR Framework: Getting started with the PVRApi Vulkan and OpenGL ES abstraction”

Leave a Comment

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

Right or wrong? Looking back at our 2018 predictions

When we gazed into our crystal ball at the end of 2017, we made several predictions for 2018. I’m pleased to say that we weren’t far off the mark on most of them. In this post, we revisit our 2018

What is PowerVR Automotive? Register NOW to hear our webinar.

The automotive industry is going through many changes and that is having a huge impact on the semiconductor IP industry. The vehicle will move from being predominantly mechanical to primarily a computer on wheels enabling a future of self-driving cars,

Image-based lighting

PowerVR Tools and SDK 2018 Release 2 now available

Here’s an early Christmas present for graphics developers – the release of the latest version of our PowerVR Tools and SDK! The headline features for this release include some exciting new examples demonstrating new techniques in our SDK, and some very

on stage in China

PVRIC4 a hit at ICCAD 2018 in China

Imagination’s PVRIC4 image compression tech garnered plenty of attention at the recent ICCAD China 2018 symposium, which took place on 29th and 30th November at the Zhuhai International Convention & Exhibition Centre, China. The annual event focusses on integrated circuit

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.