Quantcast
Channel: Intel Developer Zone Articles
Viewing all 3384 articles
Browse latest View live

Profiling DPDK Code with Intel® VTune™ Amplifier

$
0
0

Introduction      

 Performance is a key factor in designing and shipping best of class products. Optimizing performance requires visibility into system behavior. Here in this paper focus is given on using Intel® VTune™ Amplifier to profile DPDK code.

The reader will find this paper as a comprehensive reference and cook book style guidelines to install and use Intel® VTune™ Amplifier and run and profile couple of DPDK micro benchmarks (often referred as the best kept secret) as an example of getting deep visibility into system, cores communication and core pipeline and usage.

Extensive screenshots are given for the readers to compare their output with the screenshots. The commands are given, in addition, so that the readers can copy and paste the commands wherever possible.

About The Author

 mjay

M Jay has worked with the DPDK team from 2009 onwards. M Jay joined Intel in 1991 and has been in various roles and divisions with Intel – 64 bit CPU front side bus architect, 64 bit HAL developer to mention a few before DPDK team. M Jay holds 21 US Patents, both individually and jointly, all issued while working in Intel.

Outline

  • Install Linux*
  • Install Data Plane Development Kit (DPDK)
  • Install the tools
    • Source editor
    • Intel® VTune™ Amplifier
  • Install & Profile the application of your choice
    • Distributor Application
    • Ring Tests Application
  • Conclusion and Next Steps

Install Linux

From the Linux DVD with iso image

 http://old-releases.ubuntu.com/releases/15.04/ubuntu-15.04-desktop-amd64.iso

Prior to Install:

If you have a laptop installed with Windows* 8, go to safe mode (SHIFT+RESTART).

Once in safe mode, choose boot option # 1 to boot from the external USB DVD drive.  

Restart and install.

NOTE: In this paper, for example, we have installed Ubuntu* 15.04. Please refer for system details in Appendix 3.

After Install:

  • Verify whether the kernel version installed is the correct version as per the DPDK release notes.

$uname –a

image 1

The above output verifies the Kernel release as 3.19.0-59-generic, the version number as #66, and the distro as Ubuntu 64 bit.

$uname –v

Gives the version # – version #66 as shown below.

$lsb_release –c

Gives the code name – the code name is vivid as shown below.

image2

  • Verify Internet connectivity. In some cases the network-manager service has to be restarted for the Ethernet service to be operational.

$ sudo service network-manager restart

image3

The next step is to install the DPDK.

Download DPDK

  • Get the latest DPDK release as shown below and in the screenshot.

sudo wget www.dpdk.org/browse/dpdk/snapshot/dpdk-16.04.tar.xz

dpdk1

The response for the above command is as shown below.

dpdk2

You will find the DPDK tar file downloaded as shown below.

ls

dpdk3

  • Extract the tar ball.

tar xf dpdk-16.04.tar.xz

  • You will find that the directory dpdk-16.04 was created.

ls

dpdk4

  • Change to the DPDK directory to list the files.

cd dpdk-16.04

$ ls –al

dpdk5

Install the Tools

Install the source editor of your choice. Here, CSCOPE is chosen.

  • First check to see whether the correct repository is enabled.

Check that the universe repository is enabled by inspecting '/etc/apt/sources.list'

sudo gedit /etc/apt/sources.list

As highlighted below, you may see “restricted” [both  highlighted and the line below] and not having “universe”

tools1

In that case, edit the file by replacing “restricted” with “universe” [both highlighted and the line below], as shown below.

tools2

Now save the file.

  • Update the system.

sudo apt-get update

tools3

The system gets the updating as shown below.

tools4

Install CSCOPE.

sudo apt-get install cscope

tools5

As shown above, CSCOPE 15.8a-2 is installed.

Install Kernel Debug Symbols

  • The first step is to add the repository containing debugging symbols.
  • For that, first create a new file ddebs.list (if it does not exist already).  

cat /dev/null > /etc/apt/sources.list.d/ddebs.list

  • Next edit the file.

gedit /etc/apt/sources.list.d/ddebs.list

  • Add the following line to /etc/apt/sources.list.d/ddebs.list as shown below and save it.

deb http://ddebs.ubuntu.com/ vivid main restricted universe multiverse  

  • Update the system to load the package list from the new repository.

sudo apt-get update

In this case, the system gave the following error.

If you don’t see the resolution error in your system, skip the instructions here that are colored in red and proceed to the next section.

  • To resolve name servers:

sudo gedit /etc/resolvconf/resolv.conf.d/tail

  • Add these two name servers (below).
  • Save the file.
  • Restart the service.

$ sudo /etc/init.d/resolveconf restart

If the sudo apt-get update is done now without resetting the system, it still gives the resolve error.

It is recommended to shut down and restart the system.

  • After the shutdown and restart, restart the service.

sudo /etc/init.d/resolvconf restart

  • Update the system.

sudo apt-get update

With the above steps, access to http://ddebs.ubuntu.com has been resolved.

However there is a new error “GPG error” as shown at the bottom of the screenshot above.

  • Add the GPG key.

sudo apt-key adv –keyserver pool.sks-keyservers.net –recv-keys C8CAB6595FDFF622

With the repository added, the next step is to install the symbol package by running the following command:

apt-get install linux-image-<release>-dbgsym=<release>.<version>

With the release as 3.19.0-59-generic and the version as 66 this is:

apt-get install linux-image-3.19.0-59-generic-dbgsym=3.19.0-59.66      

Please note that the above resulted in an error because it could not locate the package linux-image-3.19.0-59-generic-dbgsym. If you want to set breakpoints by function names and viewing local variables, this error must be resolved.

Install the Linux Source Package

sudo apt-get install linux-source-3.19.0=3.19.0-59.66

  • With the package now installed, go to /usr/src/linux-source-3.19.0 and unpack the source tarball.

cd /usr/src/linux-source-3.19.0

$ tar xjf linux-source-3.19.0.tar.bz2

Set Up Intel® VTune Amplifier

Click https://software.intel.com/en-us/intel-vtune-amplifier-xe to get to the following Intel VTune Amplifier download page.

The product comes with multiple options (examples: for Windows, for Linux*, with only C /C++, or with Fortran and C/C++. Select the option you want as shown below.

After you submit your selection, you will get a separate e-mail with 1) serial number, 2) license file attached and 3) download location as shown in the screenshot below.

After clicking Download, you will be presented with two options as shown in the screenshot below, with the default option selected for single install package with all components.

Note that in addition to the getting started guide for Intel VTune Amplifier, there are three other useful documents as shown in the screenshot below:  the release notes, ReadMe, and the installation guide.

Access the Intel VTune Amplifier Getting Started Guide at

https://software.intel.com/en-us/node/544004

For hardware event-based sampling, verify the sampling driver is installed properly as shown in

https://software.intel.com/en-us/sep_driver

The Intel VTune Installation Guide is at https://software.intel.com/en-us/Intel-VTune-Amplifier-XE-Install-Guide-Linux

Later when you untar the Intel VTune Amplifier package, you will find the installation guide’s PDF file that comes with the package. It is recommended that you use that file.

You can access Intel VTune Amplifier ReadMe at https://software.intel.com/en-us/articles/intel-parallel-studio-xe-2016-update-3-readme

Access Intel VTune Amplifier release notes at

https://software.intel.com/en-us/articles/intel-vtune-amplifier-xe-release-notes

At this point you have six different important items.

  • Image – parallel_studio_xe_2016_update3.tgz
  • Serial number
  • License file
  • Release notes
  • ReadMe file
  • Installation guide

Registering your product with the serial number

Register your product at https://registrationcenter.intel.com/en/ so that when you install (using serial number method, if you choose) successful authentication is possible.

Since VTune supports Ubuntu 15.10 from update 2 and later, and since we’re using Intel VTune Amplifier update 3 Ubuntu 15.04, our Ubuntu version is verified as being supported with the Intel VTune Amplifier version we are using, as per the release notes.

Please take time to read the release notes, ReadMe file, and installation guide. Taking notes and highlighting the steps you need to do will make following the steps easier. 

  • Note the serial number you got through e-mail.
  • Download the License File, .lic (shown in the download folder below)

Untar the Intel VTune Amplifier Package

tar –zxvf parallel_studio_xe_2016_update3.tgz

You will see the following output as an example. Specifically, a new directory has been created named parallel_studio_xe_2016_update3

Some of the files are noteworthy.

cd parallel_studio_xe_2016_update3

$ ls

Note that Install_Guide.pdf resides in the directory shown above. Since this directory comes with the package, following this installation guide is more suitable for these installation steps.

install_GUI.sh and install.sh are the install files for GUI and the command line, respectively.

silent.cfg is the configuration file used in non-interactive (that is, silent) mode for installation.

VTune Installation Steps

In this example, we will use interactive installation and install_GUI.sh.

$ ./install_GUI.sh

The resulting successive screens with queries are shown in Appendix 1.

Verify and compare notes with your screen outputs to those shown in Appendix 1.

Following are the steps after successful complete installation.

Verifying whether the driver is installed

By default, using interrupt sampling mode should work indicating the driver is installed correctly. If interrupt sampling mode is not working properly, verify whether the driver is installed correctly. The verification steps are listed in Appendix 2.

Following are the steps after successful verification.

Before Starting Intel VTune Amplifier

Before starting Intel VTune Amplifier, let’s take a quick look at the directory structure and the key files.

amplxe-vars.sh and amplxe-vars.csh shown below are for setting environment variables.

Please note the softlinks vtune_amplifier_xe_2016 and vtune_amplifier_xe are listed below.

Starting Intel VTune Amplifier

Note that <install_dir> is /opt/intel/vtune_amplifier_xe_2016

  • Set up the environment variables.

source <install_dir>/amplxe-vars.sh  translates to 

source /opt/inte/vtune_amplifier_xe_2016/amplxe-vars.sh

  • Launch Intel VTune Amplifier in graphic mode.

amplxe-gui

You will see Intel VTune Amplifier launching as shown below.

Click Getting Started in the welcome banner to open the Getting Started instructions specific to the Intel VTune Amplifier installed.

Now you can start building your project as per the steps shown in the Getting Started notes.

In this paper, we will profile couple of DPDK performance functions to illustrate VTune profiling of DPDK code.

 

Stepping Back & Seeing the Big Picture

It behooves to step back and see the big picture first – as what other components exist in the system. If there is some unrelated component consuming resources and if we only focus on measuring our specific application, then we may be coming to wrong conclusion because of partial information.

So, here, even before running DPDK application, we are just running top –H and see where CPU is spending its cycles even without our specific application running.

Below you will see VTune showing top –H  running as well as web browser running. Now the user can understand that top is something user just ran whereas web browser is something he does not want to take CPU cycles while running the application of interest. Similarly the user may find some unwanted daemons. So, the user stops the unwanted applications, daemons and any other components.

Pointing to the Source Directory

The following screenshot shows in VTune how to point to the source directory of the s/w components of interest. You can add multiple directories.

Profiling DPDK code with VTune

1. Reserving Huge Page Creating /mnt/huge and mounting as hgetlbfs:

cd /home/dpdk/dpdk-16.04

sudo su

echo 128 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Please note that 128 is chosen here with memory constrain in the laptop chosen. In case you are using server/desktop 1024 can be chosen.

2. Creating /mnt/huge and mounting as hgetlbfs:

sudo bash

mkdir –p –v /mnt/huge    [-v for verbose, as you can see below response from the system]

mount –t hugetlbfs nodev /mnt/huge

Making the mount point permanent across reboots, by adding the following line to the /etc/fstab file:

nodev /mnt/huge hugetlbfs defaults 0 0

3. Building DPDK Test Application & DPDK Library:

export RTE_SDK=/home/dpdk/dpdk-16.04

$ export RTE_TARGET=x86_64-native-linuxapp-gcc

export EXTRA_CFLAGS=’-g’    [For DPDK symbols]

make install T=x86_64-native-linuxapp-gcc DESTDIR=install

The output of build will complete successfully as shown below.

4. Enable Userspace IO for DPDK by Loading uio Modules:

sudo modprobe uio

$ sudo insmod x86_64-native-linuxapp-gcc/kmod/igb_uio.ko

5. Add path to Symbols (DPDK Test Application) in VTune:

You can verify the symbols in the above directory in .map file

Profiling DPDK Code with VTune Amplifier

cd /home/dpdk/dpdk-16.04/x86_64-native-linuxapp-gcc/app

$ sudo su

./test

The test will issue prompt RTE>> as shown below.

?  will give the list of tests and help.

Next we will run a handful of microbenchmarks.

Profiling Distributor Perf Autotest

RTE>> distributor_perf_autotest

The summary highlights CPI rate indicating it is beyond the normal range. It also highlights “Back End Bound” indicating memory bound application nature.

The details are shown below:

The Function/Call Stack indicates rte_distributor_poll_pkt consumes CPI rate of 3.720 and _mm_pause consuming CPI rate of 3.867.

You can observe rte_distributor_get_pkt runs with CPI rate of 26.30. However it is not highlighted since it does not run as many clock ticks as other functions.

You will see other functions listed here along with the CPI each one takes – rte_distributor_processrte_distributor_request_pkt, time_cache_line_switch for instance.

Profiling Rings

The Communication between cores for interprocessor communication as well as communication between cores and NIC happens through rings and descriptors.

While NIC hardware does optimizations in terms of RS bit and DD bit (Descriptor Done bit) in bunching the data size, DPDK in addition enhances bunching with amortizing by offering API for bulk communication through rings.

The rings tests show Single producer single consumer (SP/SC) with bulk sizes both in enqueue / dequeue gives best performance compared to Multiple producers multiple consumers (MP/MC). Below are the steps.

Profiling  ring_perf_autotest

Below the rings tests show in detail that the code is backend bound and you can see the call stack showing the Single producer single consumer (SP/SC) with bulk sizes as well Multiple producers multiple consumers (MP/MC).

To appreciate relative performance of SP/SC with single data size and bulk size and comparing with MP/MC with single data size and bulk size following graph can be referred. Please note the impact of core placement – a) siblings, b) within the same socket, c) across multi sockets.

Conclusion & Next Steps

Practice profiling on additional sample DPDK applications. With the experience you gather, extend the profiling and optimization to your own applications that you are building on top of DPDK.

Get plugged into the DPDK community to learn on the latest from developers and architects and keep your products highly optimized. Register at http://www.dpdk.org/ml/listinfo/dev

Reference

Enabling Internet connectivity:

http://askubuntu.com/questions/641591/internet-connection-not-working-in-ubuntu-15-04

Getting Kernel Symbols/Sources on Ubuntu Linux:

http://sysprogs.com/VisualKernel/tutorials/setup/ubuntu/

How to debug libraries in Ubuntu:

http://stackoverflow.com/questions/14344654/how-to-use-debug-libraries-on-ubuntu

How to install a package that contains Ubuntu debug symbols:

http://askubuntu.com/questions/197016/how-to-install-a-package-that-contains-ubuntu-kernel-debug-symbols

Debug symbol packages:

https://wiki.ubuntu.com/Debug%20Symbol%20Packages

Ask Ubuntu for challenges in Apt-get update failure to fetch:

http://askubuntu.com/questions/135932/apt-get-update-failure-to-fetch-cant-connect-to-any-sources

DNS Name Server IP Address:

http://www.cyberciti.biz/faq/ubuntu-linux-configure-dns-nameserver-ip-address/

How to fix Public Key is not available issue:

https://chrisjean.com/fix-apt-get-update-the-following-signatures-couldnt-be-verified-because-the-public-key-is-not-available/

Ubuntu Key server: http://keyserver.ubuntu.com:11371/

Installing CSCOPE:

 http://installion.co.uk/ubuntu/vivid/init/c/cscope/install/index.html

http://freecode.com/projects/cscope

Performance optimization:

http://www.agner.org/optimize/instruction_tables.pdf

Intel VTune Amplifier data collection:

https://software.intel.com/en-us/articles/data-collection

Using Intel VTune Amplifier with a virtual machine:

https://software.intel.com/en-us/node/638180

Challenges in installing VTune? Refer these links below:

https://software.intel.com/en-us/forums/intel-vtune-amplifier-xe/topic/340649

http://software.intel.com/en-us/articles/vtune-amplifier-xe-2013-u3-works-on-customized-embedded-linux-system

http://softwareproducts.intel.com/ilc/

Appendix 1: Intel VTune Amplifier Install Steps

For the input ./install_GUI.sh following are the screen outputs.

  1. Welcome Screen
  2. Prerequisites
  3. End User License Agreement
  4. Activation Using Serial Number
  5. Intel® Software Improvement Program
  6. Options
  7. Installation of Open Source Components
  8. Installation starts with all the above-selected items
  9. Installation complete

The following three steps and associated screenshots are recommended for gaining additional insight in using Intel® VTune™ Amplifier.

  1. Click Finish to view the file on the local machine at  file:///opt/intel/documentation_2016/en/ps2016/getstart_prof_lc.htm
  2. To see a product tour with videos and sample apps
    https://software.intel.com/en-us/articles/evaluate-ipsxe-professional-linux
  3. To evaluate Intel® Parallel Studio XE access, view the local file on the local machine at 
    file:///opt/intel/documentation_2016/en/ps2016/startup_prof_lc.htm

Appendix 2

Please run the steps in the installation guide to verify the driver’s proper installation.

Appendix 3

System Details

Legal Disclaimer

Intel technologies’ features and benefits depend on system configuration and may require enabled hardware, software or service activation. Learn more at intel.com, or from the OEM or retailer.

No computer system can be absolutely secure.

Tests document performance of components on a particular test, in specific systems. Differences in hardware, software, or configuration will affect actual performance. Consult other sources of information to evaluate performance as you consider your purchase.  For more complete information about performance and benchmark results, visit http://www.intel.com/performance.    

Intel, the Intel logo and others are trademarks of Intel Corporation in the U.S. and/or other countries. *Other names and brands may be claimed as the property of others.

© 2016 Intel Corporation.


vHost User Multiqueue for Open vSwitch* with DPDK: Basic configuration and usage

$
0
0

This article describes how to configure vHost-user with multiqueue for a virtual machine (VM) connected to Open vSwitch (OVS) with the Data Plane Development Kit (DPDK). It was written with network admin users in mind who want to use the vHost-user multiqueue configuration for increased bandwidth to VM vHost-user port types in their Open vSwitch with DPDK server deployment.  

At the time of this writing, vHost-user multiqueue for OVS with DPDK is available in Open vSwitch 2.5, which can be downloaded here. If using Open vSwitch 2.5, the installation steps for OVS with DPDK can be found here.

You can also use the OVS master branch, which can be downloaded here if you want to have access to the latest development features. If using the OVS master branch, installation steps for OVS with DPDK can be found here

Note: As setup and component requirements differ for OVS with DPDK between Open vSwitch 2.5 and Open vSwitch master, be sure to follow the installation steps relevant to your Open vSwitch deployment.

vHost-user Multiqueue in OVS with DPDK

Before we configure vHost-user multiqueue, let’s first discuss how it is different from the standard vHost-user (that is, a single queue). Figure 1 shows a standard single queue configuration of vHost-user.


Figure 1:vHost-user default configuration.

The illustration is divided into three parts.

Hardware: a network interface card (NIC) configured with one queue (Q0) by default; a queue consists of a reception (rx) and transmission (tx) path.

Host: the host runs the vSwitch (in this case OVS with DPDK). The vSwitch has a DPDK port (‘DPDK0’) to transmit and receive traffic from the NIC. It has a vHost-user port (‘vHost-user0’) to transmit and receive traffic from a VM. It also has a single Poll Mode Driver thread (PMD 0) by default that is responsible for executing transmit and receive actions on both ports.

Guest: A VM. This is configured with a Virtual NIC (VNIC). A VNIC can be used as a kernel network device or as a DPDK interface in the VM. When a vHost-user port is configured by default, only one queue (Q0) can be used in the VNIC. This is a problem as a single queue can be a bottleneck; all traffic sent and received from the VM can only pass through this single queue.

vHost-user multiqueue resolves this problem by allowing multiple queues to be used in the VNIC in the VM. This provides a method to scale out performance when using vHost-user ports. Figure 2 describes the setup required for two queues to be configured in the VNIC with vHost-user multiqueue.


Figure 2:vHost-user multiqueue configuration with two queues.

In this configuration, notice the change in each component.

Hardware: The NIC is now configured with two queues (Q0 and Q1). The number of queues used in the VNIC is matched with the number of queues configured in the hardware NIC. Receive Side Scaling (RSS) is used to distribute ingress traffic among the queues on the NIC.

Host: The vSwitch is now configured with two PMD threads. Each queue is handled by a separate PMD thread so that the load for a VNIC is spread across multiple PMDs.

Guest: The VNIC in the guest is now configured with two queues (Q0 and Q1). The number of queues configured in the VNIC dictates the minimum number of PMDs and rx queues required for optimal distribution.

Test Environment


Figure 3: Test environment.

This article covers two use cases in which vHost-user multiqueue will be configured and verified within this guide. 

  1. vHost-user multiqueue using kernel driver (virtio-net) in guest.
  2. vHost-user multiqueue with DPDK driver (igb_uio) in guest.

Note: Both the host and the VM used in this setup run Fedora* 22 Server 64bit with Linux* kernel 4.4.6. DPDK 16.04 is also used in both the host and VM. QEMU* 2.5 is used on the host for launching the VM with vHost-user multiqueue, which connects the VM to the vSwitch bridge.

The setup of the following components remains the same in both use cases:

Test traffic configuration

The traffic generator is external and connected to the vSwitch via a NIC. There is no specific traffic generator recommended for these tests; traffic generated via software or hardware can be used. However to confirm vHost-user multiqueue functionality, multiple flows are required (a minimum of two flows). Below are examples of three flows that can be configured and should cause traffic to be distributed between the multiple queues.

Notice that the destination IP varies. This is required in order for RSS to be used on the NIC. When using a NIC with vHost-multiqueue this is a required property for ingress traffic. All other fields can remain the same for testing purposes.

NIC configuration

The NIC used for this article is an Intel® Ethernet Converged Network Adapter XL710 but other NICs can also be used; a list of NICs that are supported by DPDK can be found here. The NIC has been bound to the ‘igb_uio’ driver on the host system. Steps for building the DPDK and binding a NIC to ‘igb_uio’ can be found in the INSTALL.DPDK.md document that is packaged with OVS. The NIC is connected to the traffic generator. Rx queues for the NIC are configured at the vSwitch level.

vSwitch configuration

Follow the commands to launch the vSwitch with the DPDK in INSTALL.DPDK.md. Once the vSwitch is launched with the DPDK, configure it with the following commands.

Add a bridge ‘br0’ as type netdev.

ovs-vsctl add-br br0 -- set Bridge br0 datapath_type=netdev

Add physical port as ‘dpdk0’, as port type=dpdk and request ofport=1.

ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk ofport_request=1

Add vHost-user port as ‘vhost-user0’, as port type= dpdkvhostuser and request ofport=2.

ovs-vsctl add-port br0 vhost-user0 -- set Interface vhost-user0 type=dpdkvhostuser ofport_request=2

Delete any existing flows on the bridge.

ovs-ofctl del-flows br0

Configure flow to send traffic received on port 1 to port 2 (dpdk0 to vhost-user0).

ovs-ofctl add-flow br0 in_port=1,action=output:2

Set the PMD thread configuration to two threads to run on the host. In this example core 2 and core 3 on the host are used.

ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=C

Set the number of receive queues for the physical port ‘dpdk0’ to 2.

ovs-vsctl set Interface dpdk0 options:n_rxq=2

Set the number of receive queues for the vHost-user port ‘vhost-user0’ to 2.

ovs-vsctl set Interface vhost-user0 options:n_rxq=2

Guest VM Configuration

The QEMU parameters required to launch the VM and the methods by which multiple queues are configured within the guest will vary depending on whether the VNIC is used as a Kernel interface or as a DPDK port. The following sections deal with the specific commands required for each use case.

vHost-user Multiqueue with Kernel Interface in Guest


Figure 4: vHost-user multiqueue using kernel driver (virtio-net) in guest.

Once the vSwitch has been configured as described in the Test Environment section, launch the VM with QEMU (QEMU 2.5 was used for this test case). Launch the VM with the following sample command:

./qemu/x86_64-softmmu/qemu-system-x86_64 -cpu host -smp 2,cores=2 -hda /root/fedora-22.img -m 2048M --enable-kvm -object memory-backend-file,id=mem,size=2048M,mem-path=/dev/hugepages,share=on -numa node,memdev=mem -mem-prealloc -chardev socket,id=char1,path=/usr/local/var/run/openvswitch/vhost-user0 -netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce,queues=2 -device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1,mq=on,vectors=6

The parameters of particular relevance to vHost-user multiqueue here are the following:

The vector value is computed with ‘number of queues x 2 + 2'. The example configures two queues for the VNIC, which requires six vectors (2 x 2 + 2).

Once launched, use the following commands to configure eth0 with multiple queues.

Check the channel configuration for the virtio devices with the following:

ethtool -l eth0

Note that the Pre-set maximum for combined channels is 2, but the current hardware settings combined channels is 1. The number of combined channels must be set to 2 in order to use multiqueue. This can be done with the following command

ethtool -L eth0 combined 2

Examining the channel configuration with ‘ethtool  -l eth0’ now shows that two combined channels have been configured.

Configure eth0, arp entries and route ip rules in the VM.

ifconfig eth0 5.5.5.1/24 up

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.rp_filter=0

ip route add 6.6.6.0/24 dev eth0
route add default gw 6.6.6.6 eth0
arp -s 6.6.6.6 00:00:07:00:0E:00

ip route add 1.1.1.0/24 dev eth0
route add default gw 1.1.1.1 eth0
arp -s 1.1.1.1 DE:AD:BE:EF:CA:FA

ip route add 2.1.1.0/24 dev eth0
route add default gw 2.1.1.2 eth0
arp -s 2.1.1.2 DE:AD:BE:EF:CA:FB

ip route add 3.1.1.0/24 dev eth0
route add default gw 3.1.1.3 eth0
arp -s 3.1.1.3 DE:AD:BE:EF:CA:FC

Once these steps are complete, start the traffic flows. From the VM you can check that traffic is being received on both queues on eth0 with the following command:

cat /proc/interrupts

You should examine the interrupts generated for ‘virtio0-input.0’ and ‘virtio0-input.1’ as interrupts here will signify packets arriving on input queue 0 and 1 for eth0. Note that if the test traffic is generated at a high rate you will not see interrupts, because QEMU switches to PMD mode when processing traffic on the eth0 interface. If this occurs, lower the transmission rate and interrupts will be generated again by QEMU.

vHost-user Multiqueue with DPDK Port in Guest


Figure 5: vHost-multiqueue with DPDK driver (igb_uio) in guest.

Once the vSwitch has been configured as described in the Test Environment section, launch the VM with QEMU (QEMU 2.5 was used for this test case). The VM can be launched with the following sample command:

./qemu/x86_64-softmmu/qemu-system-x86_64 -cpu host -smp 5,cores=5 -hda /root/fedora-22.img -m 4096M --enable-kvm -object memory-backend-file,id=mem,size=4096M,mem-path=/dev/hugepages,share=on -numa node,memdev=mem -mem-prealloc -chardev socket,id=char1,path=/usr/local/var/run/openvswitch/vhost-user0 -netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce,queues=2 -device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1,mq=on,vectors=6

The parameters of particular relevance to vHost-user multiqueue here are the following:

In this test case we are using DPDK 16.04 in the guest, specifically the test-pmd application. The DPDK can be downloaded here; a quick start guide on how to build and compile DPDK can be found here.

Once the DPDK has been built and the eth0 interface attached to the ‘igb_uio’ driver, navigate to the test-pmd directory and make the application.

cd dpdk/app/test-pmd/

make

Test-pmd is a sample application that can be used to test the DPDK in a packet forwarding mode. It also provides features, such as queue stat mapping, that is useful for validating vHost-user multiqueue.

Run the application with the following command:

./testpmd -c 0x1F -n 4 --socket-mem 1024 -- --burst=64 -i --txqflags=0xf00 --dissable-hw-vlan --rxq=2 --txq=2 --nb-cores=4

The core mask of 0x1F allows test-pmd to use all five cores in the VM; however one core will be used for running the application command line while four cores will be used for running the forwarding engines. It is important to note here that we set the number of rxq and txq to 2 and that we set the nb-cores to 4 (each rxq and txq requires one core at a minimum). A detailed explanation of each test-pmd parameter as well as expected usage can be found here.

Once test-pmd has launched, enter the following commands at the command prompt:

set stat_qmap rx 0 0 0 # Map rx stats from port 0, queue 0 to queue map 0
set stat_qmap rx 0 1 1  # Map rx stats from port 0, queue 1 to queue map 1
set fwd rxonly          # Configure test-pmd to process rx operations only

start                   # Start test-pmd packet processing operations

Now start the test traffic flows on the traffic generator. While traffic is flowing, use the following command to examine the queue stats for port 0.

show port stats 0       # Display the port stats for port 0

You should see traffic arriving over queue0 and queue 1 as shown below.

Conclusion

In this article we showed two use cases for using vHost-user multiqueue with a VM on OVS with the DPDK. These use cases were kernel interface in the guest and DPDK interface in the guest. We demonstrated the utility commands to configure mutliqueue at the vSwitch, QEMU, and VM levels. We described the type of test traffic required for multiqueue and demonstrated how to examine and verify multiqueue is working correctly in both a kernel interface and DPDK port inside the guest.

About the Author

Ian Stokes is a network software engineer with Intel. His work is primarily focused on accelerated software switching solutions in the user space running on Intel® architecture. His contributions to Open vSwitch with DPDK include the OVS DPDK QoS API and egress/ingress policer solutions.

Additional Information

Have a question? Feel free to follow up with the query on the Open vSwitch discussion mailing thread.

To learn more about Open vSwitch with DPDK in general, we encourage you to check out the following videos and articles in the Intel® Developer Zone and Intel® Network Builders University.

QoS Configuration and usage for Open vSwitch with DPDK

Rate Limiting Configuration and Usage for Open vSwitch with DPDK

Open vSwitch with DPDK Architectural Deep Dive

DPDK Open vSwitch: Accelerating The Path to the Guest

Intel® XDK FAQs - General

$
0
0

How can I get started with Intel XDK?

There are plenty of videos and articles that you can go through here to get started. You could also start with some of our demo apps. It may also help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, which will help you understand some of the differences between developing for a traditional server-based environment and developing for the Intel XDK hybrid Cordova app environment.

Having prior understanding of how to program using HTML, CSS and JavaScript* is crucial to using the Intel XDK. The Intel XDK is primarily a tool for visualizing, debugging and building an app package for distribution.

You can do the following to access our demo apps:

  • Select Project tab
  • Select "Start a New Project"
  • Select "Samples and Demos"
  • Create a new project from a demo

If you have specific questions following that, please post it to our forums.

Can I use an external editor for development in Intel® XDK?

Yes, you can open your files and edit them in your favorite editor. However, note that you must use Brackets* to use the "Live Layout Editing" feature. Also, if you are using App Designer (the UI layout tool in Intel XDK) it will make many automatic changes to your index.html file, so it is best not to edit that file externally at the same time you have App Designer open.

Some popular editors among our users include:

  • Sublime Text* (Refer to this article for information on the Intel XDK plugin for Sublime Text*)
  • Notepad++* for a lighweight editor
  • Jetbrains* editors (Webstorm*)
  • Vim* the editor

How do I get code refactoring capability in Brackets* (the Intel XDK code editor)?

...to be written...

Why doesn’t my app show up in Google* play for tablets?

...to be written...

What is the global-settings.xdk file and how do I locate it?

global-settings.xdk contains information about all your projects in the Intel XDK, along with many of the settings related to panels under each tab (Emulate, Debug etc). For example, you can set the emulator to auto-refresh or no-auto-refresh. Modify this file at your own risk and always keep a backup of the original!

You can locate global-settings.xdk here:

  • Mac OS X*
    ~/Library/Application Support/XDK/global-settings.xdk
  • Microsoft Windows*
    %LocalAppData%\XDK
  • Linux*
    ~/.config/XDK/global-settings.xdk

If you are having trouble locating this file, you can search for it on your system using something like the following:

  • Windows:
    > cd /
    > dir /s global-settings.xdk
  • Mac and Linux:
    $ sudo find / -name global-settings.xdk

When do I use the intelxdk.js, xhr.js and cordova.js libraries?

The intelxdk.js and xhr.js libraries were only required for use with the Intel XDK legacy build tiles (which have been retired). The cordova.js library is needed for all Cordova builds. When building with the Cordova tiles, any references to intelxdk.js and xhr.js libraries in your index.html file are ignored.

How do I get my Android (and Crosswalk) keystore file?

New with release 3088 of the Intel XDK, you may now download your build certificates (aka keystore) using the new certificate manager that is built into the Intel XDK. Please read the initial paragraphs of Managing Certificates for your Intel XDK Account and the section titled "Convert a Legacy Android Certificate" in that document, for details regarding how to do this.

It may also help to review this short, quick overview video (there is no audio) that shows how you convert your existing "legacy" certificates to the "new" format that allows you to directly manage your certificates using the certificate management tool that is built into the Intel XDK. This conversion process is done only once.

If the above fails, please send an email to html5tools@intel.com requesting help. It is important that you send that email from the email address associated with your Intel XDK account.

How do I rename my project that is a duplicate of an existing project?

See this FAQ: How do I make a copy of an existing Intel XDK project?

How do I recover when the Intel XDK hangs or won't start?

  • If you are running Intel XDK on Windows* it must be Windows* 7 or higher. It will not run reliably on earlier versions.
  • Delete the "project-name.xdk" file from the project directory that Intel XDK is trying to open when it starts (it will try to open the project that was open during your last session), then try starting Intel XDK. You will have to "import" your project into Intel XDK again. Importing merely creates the "project-name.xdk" file in your project directory and adds that project to the "global-settings.xdk" file.
  • Rename the project directory Intel XDK is trying to open when it starts. Create a new project based on one of the demo apps. Test Intel XDK using that demo app. If everything works, restart Intel XDK and try it again. If it still works, rename your problem project folder back to its original name and open Intel XDK again (it should now open the sample project you previously opened). You may have to re-select your problem project (Intel XDK should have forgotten that project during the previous session).
  • Clear Intel XDK's program cache directories and files.

    On a Windows machine this can be done using the following on a standard command prompt (administrator is not required):

    > cd %AppData%\..\Local\XDK
    > del *.* /s/q

    To locate the "XDK cache" directory on [OS X*] and [Linux*] systems, do the following:

    $ sudo find / -name global-settings.xdk
    $ cd <dir found above>
    $ sudo rm -rf *

    You might want to save a copy of the "global-settings.xdk" file before you delete that cache directory and copy it back before you restart Intel XDK. Doing so will save you the effort of rebuilding your list of projects. Please refer to this question for information on how to locate the global-settings.xdk file.
  • If you save the "global-settings.xdk" file and restored it in the step above and you're still having hang troubles, try deleting the directories and files above, along with the "global-settings.xdk" file and try it again.
  • Do not store your project directories on a network share (Intel XDK currently has issues with network shares that have not yet been resolved). This includes folders shared between a Virtual machine (VM) guest and its host machine (for example, if you are running Windows* in a VM running on a Mac* host). This network share issue is a known issue with a fix request in place.
  • There have also been issues with running behind a corporate network proxy or firewall. To check them try running Intel XDK from your home network where, presumably, you have a simple NAT router and no proxy or firewall. If things work correctly there then your corporate firewall or proxy may be the source of the problem.
  • Issues with Intel XDK account logins can also cause Intel XDK to hang. To confirm that your login is working correctly, go to the Intel XDK App Center and confirm that you can login with your Intel XDK account. While you are there you might also try deleting the offending project(s) from the App Center.

If you can reliably reproduce the problem, please send us a copy of the "xdk.log" file that is stored in the same directory as the "global-settings.xdk" file to html5tools@intel.com.

Is Intel XDK an open source project? How can I contribute to the Intel XDK community?

No, It is not an open source project. However, it utilizes many open source components that are then assembled into Intel XDK. While you cannot contribute directly to the Intel XDK integration effort, you can contribute to the many open source components that make up Intel XDK.

The following open source components are the major elements that are being used by Intel XDK:

  • Node-Webkit
  • Chromium
  • Ripple* emulator
  • Brackets* editor
  • Weinre* remote debugger
  • Crosswalk*
  • Cordova*
  • App Framework*

How do I configure Intel XDK to use 9 patch png for Android* apps splash screen?

Intel XDK does support the use of 9 patch png for Android* apps splash screen. You can read up more at https://software.intel.com/en-us/xdk/articles/android-splash-screens-using-nine-patch-png on how to create a 9 patch png image and link to an Intel XDK sample using 9 patch png images.

How do I stop AVG from popping up the "General Behavioral Detection" window when Intel XDK is launched?

You can try adding nw.exe as the app that needs an exception in AVG.

What do I specify for "App ID" in Intel XDK under Build Settings?

Your app ID uniquely identifies your app. For example, it can be used to identify your app within Apple’s application services allowing you to use things like in-app purchasing and push notifications.

Here are some useful articles on how to create an App ID:

Is it possible to modify the Android Manifest or iOS plist file with the Intel XDK?

You cannot modify the AndroidManifest.xml file directly with our build system, as it only exists in the cloud. However, you may do so by creating a dummy plugin that only contains a plugin.xml file containing directives that can be used to add lines to the AndroidManifest.xml file during the build process. In essence, you add lines to the AndroidManifest.xml file via a local plugin.xml file. Here is an example of a plugin that does just that:

<?xml version="1.0" encoding="UTF-8"?><plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="my-custom-intents-plugin" version="1.0.0"><name>My Custom Intents Plugin</name><description>Add Intents to the AndroidManifest.xml</description><license>MIT</license><engines><engine name="cordova" version=">=3.0.0" /></engines><!-- android --><platform name="android"><config-file target="AndroidManifest.xml" parent="/manifest/application"><activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:launchMode="singleTop" android:name="testa" android:theme="@android:style/Theme.Black.NoTitleBar"><intent-filter><action android:name="android.intent.action.SEND" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="*/*" /></intent-filter></activity></config-file></platform></plugin>

You can inspect the AndroidManifest.xml created in an APK, using apktool with the following command line:

$ apktool d my-app.apk
$ cd my-app
$ more AndroidManifest.xml

This technique exploits the config-file element that is described in the Cordova Plugin Specification docs and can also be used to add lines to iOS plist files. See the Cordova plugin documentation link for additional details.

Here is an example of such a plugin for modifying the iOS plist file, specifically for adding a BIS key to the plist file:

<?xml version="1.0" encoding="UTF-8"?><plugin
    xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="my-custom-bis-plugin"
    version="0.0.2"><name>My Custom BIS Plugin</name><description>Add BIS info to iOS plist file.</description><license>BSD-3</license><preference name="BIS_KEY" /><engines><engine name="cordova" version=">=3.0.0" /></engines><!-- ios --><platform name="ios"><config-file target="*-Info.plist" parent="CFBundleURLTypes"><array><dict><key>ITSAppUsesNonExemptEncryption</key><true/><key>ITSEncryptionExportComplianceCode</key><string>$BIS_KEY</string></dict></array></config-file></platform></plugin>

How can I share my Intel XDK app build?

You can send a link to your project via an email invite from your project settings page. However, a login to your account is required to access the file behind the link. Alternatively, you can download the build from the build page, onto your workstation, and push that built image to some location from which you can send a link to that image.

Why does my iOS build fail when I am able to test it successfully on a device and the emulator?

Common reasons include:

  • Your App ID specified in the project settings do not match the one you specified in Apple's developer portal.
  • The provisioning profile does not match the cert you uploaded. Double check with Apple's developer site that you are using the correct and current distribution cert and that the provisioning profile is still active. Download the provisioning profile again and add it to your project to confirm.
  • In Project Build Settings, your App Name is invalid. It should be modified to include only alpha, space and numbers.

How do I add multiple domains in Domain Access?

Here is the primary doc source for that feature.

If you need to insert multiple domain references, then you will need to add the extra references in the intelxdk.config.additions.xml file. This StackOverflow entry provides a basic idea and you can see the intelxdk.config.*.xml files that are automatically generated with each build for the <access origin="xxx" /> line that is generated based on what you provide in the "Domain Access" field of the "Build Settings" panel on the Project Tab.

How do I build more than one app using the same Apple developer account?

On Apple developer, create a distribution certificate using the "iOS* Certificate Signing Request" key downloaded from Intel XDK Build tab only for the first app. For subsequent apps, reuse the same certificate and import this certificate into the Build tab like you usually would.

How do I include search and spotlight icons as part of my app?

Please refer to this article in the Intel XDK documentation. Create anintelxdk.config.additions.xml file in your top level directory (same location as the otherintelxdk.*.config.xml files) and add the following lines for supporting icons in Settings and other areas in iOS*.

<!-- Spotlight Icon --><icon platform="ios" src="res/ios/icon-40.png" width="40" height="40" /><icon platform="ios" src="res/ios/icon-40@2x.png" width="80" height="80" /><icon platform="ios" src="res/ios/icon-40@3x.png" width="120" height="120" /><!-- iPhone Spotlight and Settings Icon --><icon platform="ios" src="res/ios/icon-small.png" width="29" height="29" /><icon platform="ios" src="res/ios/icon-small@2x.png" width="58" height="58" /><icon platform="ios" src="res/ios/icon-small@3x.png" width="87" height="87" /><!-- iPad Spotlight and Settings Icon --><icon platform="ios" src="res/ios/icon-50.png" width="50" height="50" /><icon platform="ios" src="res/ios/icon-50@2x.png" width="100" height="100" />

For more information related to these configurations, visit http://cordova.apache.org/docs/en/3.5.0/config_ref_images.md.html#Icons%20and%20Splash%20Screens.

For accurate information related to iOS icon sizes, visit https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html

NOTE: The iPhone 6 icons will only be available if iOS* 7 or 8 is the target.

Cordova iOS* 8 support JIRA tracker: https://issues.apache.org/jira/browse/CB-7043

Does Intel XDK support Modbus TCP communication?

No, since Modbus is a specialized protocol, you need to write either some JavaScript* or native code (in the form of a plugin) to handle the Modbus transactions and protocol.

How do I sign an Android* app using an existing keystore?

New with release 3088 of the Intel XDK, you may now import your existing keystore into Intel XDK using the new certificate manager that is built into the Intel XDK. Please read the initial paragraphs of Managing Certificates for your Intel XDK Account and the section titled "Import an Android Certificate Keystore" in that document, for details regarding how to do this.

If the above fails, please send an email to html5tools@intel.com requesting help. It is important that you send that email from the email address associated with your Intel XDK account.

How do I build separately for different Android* versions?

Under the Projects Panel, you can select the Target Android* version under the Build Settings collapsible panel. You can change this value and build your application multiple times to create numerous versions of your application that are targeted for multiple versions of Android*.

How do I display the 'Build App Now' button if my display language is not English?

If your display language is not English and the 'Build App Now' button is proving to be troublesome, you may change your display language to English which can be downloaded by a Windows* update. Once you have installed the English language, proceed to Control Panel > Clock, Language and Region > Region and Language > Change Display Language.

How do I update my Intel XDK version?

When an Intel XDK update is available, an Update Version dialog box lets you download the update. After the download completes, a similar dialog lets you install it. If you did not download or install an update when prompted (or on older versions), click the package icon next to the orange (?) icon in the upper-right to download or install the update. The installation removes the previous Intel XDK version.

How do I import my existing HTML5 app into the Intel XDK?

If your project contains an Intel XDK project file (<project-name>.xdk) you should use the "Open an Intel XDK Project" option located at the bottom of the Projects List on the Projects tab (lower left of the screen, round green "eject" icon, on the Projects tab). This would be the case if you copied an existing Intel XDK project from another system or used a tool that exported a complete Intel XDK project.

If your project does not contain an Intel XDK project file (<project-name>.xdk) you must "import" your code into a new Intel XDK project. To import your project, use the "Start a New Project" option located at the bottom of the Projects List on the Projects tab (lower left of the screen, round blue "plus" icon, on theProjects tab). This will open the "Samples, Demos and Templates" page, which includes an option to "Import Your HTML5 Code Base." Point to the root directory of your project. The Intel XDK will attempt to locate a file named index.html in your project and will set the "Source Directory" on the Projects tab to point to the directory that contains this file.

If your imported project did not contain an index.html file, your project may be unstable. In that case, it is best to delete the imported project from the Intel XDK Projects tab ("x" icon in the upper right corner of the screen), rename your "root" or "main" html file to index.html and import the project again. Several components in the Intel XDK depend on this assumption that the main HTML file in your project is named index.hmtl. See Introducing Intel® XDK Development Tools for more details.

It is highly recommended that your "source directory" be located as a sub-directory inside your "project directory." This insures that non-source files are not included as part of your build package when building your application. If the "source directory" and "project directory" are the same it results in longer upload times to the build server and unnecessarily large application executable files returned by the build system. See the following images for the recommended project file layout.

I am unable to login to App Preview with my Intel XDK password.

On some devices you may have trouble entering your Intel XDK login password directly on the device in the App Preview login screen. In particular, sometimes you may have trouble with the first one or two letters getting lost when entering your password.

Try the following if you are having such difficulties:

  • Reset your password, using the Intel XDK, to something short and simple.

  • Confirm that this new short and simple password works with the XDK (logout and login to the Intel XDK).

  • Confirm that this new password works with the Intel Developer Zone login.

  • Make sure you have the most recent version of Intel App Preview installed on your devices. Go to the store on each device to confirm you have the most recent copy of App Preview installed.

  • Try logging into Intel App Preview on each device with this short and simple password. Check the "show password" box so you can see your password as you type it.

If the above works, it confirms that you can log into your Intel XDK account from App Preview (because App Preview and the Intel XDK go to the same place to authenticate your login). When the above works, you can go back to the Intel XDK and reset your password to something else, if you do not like the short and simple password you used for the test.

How do I completely uninstall the Intel XDK from my system?

Take the following steps to completely uninstall the XDK from your Windows system:

  • From the Windows Control Panel, remove the Intel XDK, using the Windows uninstall tool.

  • Then:
    > cd %LocalAppData%\Intel\XDK
    > del *.* /s/q

  • Then:
    > cd %LocalAppData%\XDK
    > copy global-settings.xdk %UserProfile%
    > del *.* /s/q
    > copy %UserProfile%\global-settings.xdk .

  • Then:
    -- Goto xdk.intel.com and select the download link.
    -- Download and install the new XDK.

To do the same on a Linux or Mac system:

  • On a Linux machine, run the uninstall script, typically /opt/intel/XDK/uninstall.sh.
     
  • Remove the directory into which the Intel XDK was installed.
    -- Typically /opt/intel or your home (~) directory on a Linux machine.
    -- Typically in the /Applications/Intel XDK.app directory on a Mac.
     
  • Then:
    $ find ~ -name global-settings.xdk
    $ cd <result-from-above> (for example ~/Library/Application Support/XDK/ on a Mac)
    $ cp global-settings.xdk ~
    $ rm -Rf *
    $ mv ~/global-settings.xdk .

     
  • Then:
    -- Goto xdk.intel.com and select the download link.
    -- Download and install the new XDK.

Is there a tool that can help me highlight syntax issues in Intel XDK?

Yes, you can use the various linting tools that can be added to the Brackets editor to review any syntax issues in your HTML, CSS and JS files. Go to the "File > Extension Manager..." menu item and add the following extensions: JSHint, CSSLint, HTMLHint, XLint for Intel XDK. Then, review your source files by monitoring the small yellow triangle at the bottom of the edit window (a green check mark indicates no issues).

How do I delete built apps and test apps from the Intel XDK build servers?

You can manage them by logging into: https://appcenter.html5tools-software.intel.com/csd/controlpanel.aspx. This functionality will eventually be available within Intel XDK after which access to app center will be removed.

I need help with the App Security API plugin; where do I find it?

Visit the primary documentation book for the App Security API and see this forum post for some additional details.

When I install my app or use the Debug tab Avast antivirus flags a possible virus, why?

If you are receiving a "Suspicious file detected - APK:CloudRep [Susp]" message from Avast anti-virus installed on your Android device it is due to the fact that you are side-loading the app (or the Intel XDK Debug modules) onto your device (using a download link after building or by using the Debug tab to debug your app), or your app has been installed from an "untrusted" Android store. See the following official explanation from Avast:

Your application was flagged by our cloud reputation system. "Cloud rep" is a new feature of Avast Mobile Security, which flags apks when the following conditions are met:

  1. The file is not prevalent enough; meaning not enough users of Avast Mobile Security have installed your APK.
  2. The source is not an established market (Google Play is an example of an established market).

If you distribute your app using Google Play (or any other trusted market) your users should not see any warning from Avast.

Following are some of the Avast anti-virus notification screens you might see on your device. All of these are perfectly normal, they are due to the fact that you must enable the installation of "non-market" apps in order to use your device for debug and the App IDs associated with your never published app or the custom debug modules that the Debug tab in the Intel XDK builds and installs on your device will not be found in a "established" (aka "trusted") market, such as Google Play.

If you choose to ignore the "Suspicious app activity!" threat you will not receive a threat for that debug module any longer. It will show up in the Avast 'ignored issues' list. Updates to an existing, ignored, custom debug module should continue to be ignored by Avast. However, new custom debug modules (due to a new project App ID or a new version of Crosswalk selected in your project's Build Settings) will result in a new warning from the Avast anti-virus tool.

  

  

How do I add a Brackets extension to the editor that is part of the Intel XDK?

The number of Brackets extensions that are provided in the built-in edition of the Brackets editor are limited to insure stability of the Intel XDK product. Not all extensions are compatible with the edition of Brackets that is embedded within the Intel XDK. Adding incompatible extensions can cause the Intel XDK to quit working.

Despite this warning, there are useful extensions that have not been included in the editor and which can be added to the Intel XDK. Adding them is temporary, each time you update the Intel XDK (or if you reinstall the Intel XDK) you will have to "re-add" your Brackets extension. To add a Brackets extension, use the following procedure:

  • exit the Intel XDK
  • download a ZIP file of the extension you wish to add
  • on Windows, unzip the extension here:
    %LocalAppData%\Intel\XDK\xdk\brackets\b\extensions\dev
  • on Mac OS X, unzip the extension here:
    /Applications/Intel\ XDK.app/Contents/Resources/app.nw/brackets/b/extensions/dev
  • start the Intel XDK

Note that the locations given above are subject to change with new releases of the Intel XDK.

Why does my app or game require so many permissions on Android when built with the Intel XDK?

When you build your HTML5 app using the Intel XDK for Android or Android-Crosswalk you are creating a Cordova app. It may seem like you're not building a Cordova app, but you are. In order to package your app so it can be distributed via an Android store and installed on an Android device, it needs to be built as a hybrid app. The Intel XDK uses Cordova to create that hybrid app.

A pure Cordova app requires the NETWORK permission, it's needed to "jump" between your HTML5 environment and the native Android environment. Additional permissions will be added by any Cordova plugins you include with your application; which permissions are includes are a function of what that plugin does and requires.

Crosswalk for Android builds also require the NETWORK permission, because the Crosswalk image built by the Intel XDK includes support for Cordova. In addition, current versions of Crosswalk (12 and 14 at the time this FAQ was written)also require NETWORK STATE and WIFI STATE. There is an extra permission in some versions of Crosswalk (WRITE EXTERNAL STORAGE) that is only needed by the shared model library of Crosswalk, we have asked the Crosswalk project to remove this permission in a future Crosswalk version.

If you are seeing more than the following five permissions in your XDK-built Crosswalk app:

  • android.permission.INTERNET
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE

then you are seeing permissions that have been added by some plugins. Each plugin is different, so there is no hard rule of thumb. The two "default" core Cordova plugins that are added by the Intel XDK blank templates (device and splash screen) do not require any Android permissions.

BTW: the permission list above comes from a Crosswalk 14 build. Crosswalk 12 builds do not included the last permission; it was added when the Crosswalk project introduced the shared model library option, which started with Crosswalk 13 (the Intel XDK does not support 13 builds).

How do I make a copy of an existing Intel XDK project?

If you just need to make a backup copy of an existing project, and do not plan to open that backup copy as a project in the Intel XDK, do the following:

  • Exit the Intel XDK.
  • Copy the entire project directory:
    • on Windows, use File Explorer to "right-click" and "copy" your project directory, then "right-click" and "paste"
    • on Mac use Finder to "right-click" and then "duplicate" your project directory
    • on Linux, open a terminal window, "cd" to the folder that contains your project, and type "cp -a old-project/ new-project/" at the terminal prompt (where "old-project/" is the folder name of your existing project that you want to copy and "new-project/" is the name of the new folder that will contain a copy of your existing project)

If you want to use an existing project as the starting point of a new project in the Intel XDK. The process described below will insure that the build system does not confuse the ID in your old project with that stored in your new project. If you do not follow the procedure below you will have multiple projects using the same project ID (a special GUID that is stored inside the Intel XDK <project-name>.xdk file in the root directory of your project). Each project in your account must have a unique project ID.

  • Exit the Intel XDK.
  • Make a copy of your existing project using the process described above.
  • Inside the new project that you made (that is, your new copy of your old project), make copies of the <project-name>.xdk file and <project-name>.xdke files and rename those copies to something like project-new.xdk and project-new.xdke (anything you like, just something different than the original project name, preferably the same name as the new project folder in which you are making this new project).
  • Using a TEXT EDITOR (only) (such as Notepad or Sublime or Brackets or some other TEXT editor), open your new "project-new.xdk" file (whatever you named it) and find the projectGuid line, it will look something like this:
    "projectGuid": "a863c382-ca05-4aa4-8601-375f9f209b67",
  • Change the "GUID" to all zeroes, like this: "00000000-0000-0000-000000000000"
  • Save the modified "project-new.xdk" file.
  • Open the Intel XDK.
  • Goto the Projects tab.
  • Select "Open an Intel XDK Project" (the green button at the bottom left of the Projects tab).
  • To open this new project, locate the new "project-new.xdk" file inside the new project folder you copied above.
  • Don't forget to change the App ID in your new project. This is necessary to avoid conflicts with the project you copied from, in the store and when side-loading onto a device.

My project does not include a www folder. How do I fix it so it includes a www or source directory?

The Intel XDK HTML5 and Cordova project file structures are meant to mimic a standard Cordova project. In a Cordova (or PhoneGap) project there is a subdirectory (or folder) named www that contains all of the HTML5 source code and asset files that make up your application. For best results, it is advised that you follow this convention, of putting your source inside a "source directory" inside of your project folder.

This most commonly happens as the result of exporting a project from an external tool, such as Construct2, or as the result of importing an existing HTML5 web app that you are converting into a hybrid mobile application (eg., an Intel XDK Corodova app). If you would like to convert an existing Intel XDK project into this format, follow the steps below:

  • Exit the Intel XDK.
  • Copy the entire project directory:
    • on Windows, use File Explorer to "right-click" and "copy" your project directory, then "right-click" and "paste"
    • on Mac use Finder to "right-click" and then "duplicate" your project directory
    • on Linux, open a terminal window, "cd" to the folder that contains your project, and type "cp -a old-project/ new-project/" at the terminal prompt (where "old-project/" is the folder name of your existing project that you want to copy and "new-project/" is the name of the new folder that will contain a copy of your existing project)
  • Create a "www" directory inside the new duplicate project you just created above.
  • Move your index.html and other source and asset files to the "www" directory you just created -- this is now your "source" directory, located inside your "project" directory (do not move the <project-name>.xdk and xdke files and any intelxdk.config.*.xml files, those must stay in the root of the project directory)
  • Inside the new project that you made above (by making a copy of the old project), rename the <project-name>.xdk file and <project-name>.xdke files to something like project-copy.xdk and project-copy.xdke (anything you like, just something different than the original project, preferably the same name as the new project folder in which you are making this new project).
  • Using a TEXT EDITOR (only) (such as Notepad or Sublime or Brackets or some other TEXT editor), open the new "project-copy.xdk" file (whatever you named it) and find the line named projectGuid, it will look something like this:
    "projectGuid": "a863c382-ca05-4aa4-8601-375f9f209b67",
  • Change the "GUID" to all zeroes, like this: "00000000-0000-0000-000000000000"
  • A few lines down find: "sourceDirectory": "",
  • Change it to this: "sourceDirectory": "www",
  • Save the modified "project-copy.xdk" file.
  • Open the Intel XDK.
  • Goto the Projects tab.
  • Select "Open an Intel XDK Project" (the green button at the bottom left of the Projects tab).
  • To open this new project, locate the new "project-copy.xdk" file inside the new project folder you copied above.

Can I install more than one copy of the Intel XDK onto my development system?

Yes, you can install more than one version onto your development system. However, you cannot run multiple instances of the Intel XDK at the same time. Be aware that new releases sometimes change the project file format, so it is a good idea, in these cases, to make a copy of your project if you need to experiment with a different version of the Intel XDK. See the instructions in a FAQ entry above regarding how to make a copy of your Intel XDK project.

Follow the instructions in this forum post to install more than one copy of the Intel XDK onto your development system.

On Apple OS X* and Linux* systems, does the Intel XDK need the OpenSSL* library installed?

Yes. Several features of the Intel XDK require the OpenSSL library, which typically comes pre-installed on Linux and OS X systems. If the Intel XDK reports that it could not find libssl, go to https://www.openssl.org to download and install it.

I have a web application that I would like to distribute in app stores without major modifications. Is this possible using the Intel XDK?

Yes, if you have a true web app or “client app” that only uses HTML, CSS and JavaScript, it is usually not too difficult to convert it to a Cordova hybrid application (this is what the Intel XDK builds when you create an HTML5 app). If you rely heavily on PHP or other server scripting languages embedded in your pages you will have more work to do. Because your Cordova app is not associated with a server, you cannot rely on server-based programming techniques; instead, you must rewrite any such code to user RESTful APIs that your app interacts with using, for example, AJAX calls.

What is the best training approach to using the Intel XDK for a newbie?

First, become well-versed in the art of client web apps, apps that rely only on HTML, CSS and JavaScript and utilize RESTful APIs to talk to network services. With that you will have mastered 80% of the problem. After that, it is simply a matter of understanding how Cordova plugins are able to extend the JavaScript API for access to features of the platform. For HTML5 training there are many sites providing tutorials. It may also help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, which will help you understand some of the differences between developing for a traditional server-based environment and developing for the Intel XDK hybrid Cordova app environment.

What is the best platform to start building an app with the Intel XDK? And what are the important differences between the Android, iOS and other mobile platforms?

There is no one most important difference between the Android, iOS and other platforms. It is important to understand that the HTML5 runtime engine that executes your app on each platform will vary as a function of the platform. Just as there are differences between Chrome and Firefox and Safari and Internet Explorer, there are differences between iOS 9 and iOS 8 and Android 4 and Android 5, etc. Android has the most significant differences between vendors and versions of Android. This is one of the reasons the Intel XDK offers the Crosswalk for Android build option, to normalize and update the Android issues.

In general, if you can get your app working well on Android (or Crosswalk for Android) first you will generally have fewer issues to deal with when you start to work on the iOS and Windows platforms. In addition, the Android platform has the most flexible and useful debug options available, so it is the easiest platform to use for debugging and testing your app.

Is my password encrypted and why is it limited to fifteen characters?

Yes, your password is stored encrypted and is managed by https://signin.intel.com. Your Intel XDK userid and password can also be used to log into the Intel XDK forum as well as the Intel Developer Zone. the Intel XDK does not store nor does it manage your userid and password.

The rules regarding allowed userids and passwords are answered on this Sign In FAQ page, where you can also find help on recovering and changing your password.

Why does the Intel XDK take a long time to start on Linux or Mac?

...and why am I getting this error message? "Attempt to contact authentication server is taking a long time. You can wait, or check your network connection and try again."

At startup, the Intel XDK attempts to automatically determine the proxy settings for your machine. Unfortunately, on some system configurations it is unable to reliably detect your system proxy settings. As an example, you might see something like this image when starting the Intel XDK.

On some systems you can get around this problem by setting some proxy environment variables and then starting the Intel XDK from a command-line that includes those configured environment variables. To set those environment variables, similar to the following:

$ export no_proxy="localhost,127.0.0.1/8,::1"
$ export NO_PROXY="localhost,127.0.0.1/8,::1"
$ export http_proxy=http://proxy.mydomain.com:123/
$ export HTTP_PROXY=http://proxy.mydomain.com:123/
$ export https_proxy=http://proxy.mydomain.com:123/
$ export HTTPS_PROXY=http://proxy.mydomain.com:123/

IMPORTANT! The name of your proxy server and the port (or ports) that your proxy server requires will be different than those shown in the example above. Please consult with your IT department to find out what values are appropriate for your site. Intel has no way of knowing what configuration is appropriate for your network.

If you use the Intel XDK in multiple locations (at work and at home), you may have to change the proxy settings before starting the Intel XDK after switching to a new network location. For example, many work networks use a proxy server, but most home networks do not require such a configuration. In that case, you need to be sure to "unset" the proxy environment variables before starting the Intel XDK on a non-proxy network.

After you have successfully configured your proxy environment variables, you can start the Intel XDK manually, from the command-line.

On a Mac, where the Intel XDK is installed in the default location, type the following (from a terminal window that has the above environment variables set):

$ open /Applications/Intel\ XDK.app/

On a Linux machine, assuming the Intel XDK has been installed in the ~/intel/XDK directory, type the following (from a terminal window that has the above environment variables set):

$ ~/intel/XDK/xdk.sh &

In the Linux case, you will need to adjust the directory name that points to the xdk.sh file in order to start. The example above assumes a local install into the ~/intel/XDK directory. Since Linux installations have more options regarding the installation directory, you will need to adjust the above to suit your particular system and install directory.

How do I generate a P12 file on a Windows machine?

See these articles:

How do I change the default dir for creating new projects in the Intel XDK?

You can change the default new project location manually by modifying a field in the global-settings.xdk file. Locate the global-settings.xdk file on your system (the precise location varies as a function of the OS) and find this JSON object inside that file:

"projects-tab": {"defaultPath": "/Users/paul/Documents/XDK","LastSortType": "descending|Name","lastSortType": "descending|Opened","thirdPartyDisclaimerAcked": true
  },

The example above came from a Mac. On a Mac the global-settings.xdk file is located in the "~/Library/Application Support/XDK" directory.

On a Windows machine the global-settings.xdk file is normally found in the "%LocalAppData%\XDK" directory. The part you are looking for will look something like this:

"projects-tab": {"thirdPartyDisclaimerAcked": false,"LastSortType": "descending|Name","lastSortType": "descending|Opened","defaultPath": "C:\\Users\\paul/Documents"
  },

Obviously, it's the defaultPath part you want to change.

BE CAREFUL WHEN YOU EDIT THE GLOBAL-SETTINGS.XDK FILE!! You've been warned...

Make sure the result is proper JSON when you are done, or it may cause your XDK to cough and hack loudly. Make a backup copy of global-settings.xdk before you start, just in case.

Where I can find recent and upcoming webinars list?

How can I change the email address associated with my Intel XDK login?

Login to the Intel Developer Zone with your Intel XDK account userid and password and then locate your "account dashboard." Click the "pencil icon" next to your name to open the "Personal Profile" section of your account, where you can edit your "Name & Contact Info," including the email address associated with your account, under the "Private" section of your profile.

What network addresses must I enable in my firewall to insure the Intel XDK will work on my restricted network?

Normally, access to the external servers that the Intel XDK uses is handled automatically by your proxy server. However, if you are working in an environment that has restricted Internet access and you need to provide your IT department with a list of URLs that you need access to in order to use the Intel XDK, then please provide them with the following list of domain names:

  • appcenter.html5tools-software.intel.com (for communication with the build servers)
  • s3.amazonaws.com (for downloading sample apps and built apps)
  • download.xdk.intel.com (for getting XDK updates)
  • debug-software.intel.com (for using the Test tab weinre debug feature)
  • xdk-feed-proxy.html5tools-software.intel.com (for receiving the tweets in the upper right corner of the XDK)
  • signin.intel.com (for logging into the XDK)
  • sfederation.intel.com (for logging into the XDK)

Normally this should be handled by your network proxy (if you're on a corporate network) or should not be an issue if you are working on a typical home network.

I cannot create a login for the Intel XDK, how do I create a userid and password to use the Intel XDK?

If you have downloaded and installed the Intel XDK but are having trouble creating a login, you can create the login outside the Intel XDK. To do this, go to the Intel Developer Zone and push the "Join Today" button. After you have created your Intel Developer Zone login you can return to the Intel XDK and use that userid and password to login to the Intel XDK. This same userid and password can also be used to login to the Intel XDK forum.

Installing the Intel XDK on Windows fails with a "Package signature verification failed." message.

If you receive a "Package signature verification failed" message (see image below) when installing the Intel XDK on your system, it is likely due to one of the following two reasons:

  • Your system does not have a properly installed "root certificate" file, which is needed to confirm that the install package is good.
  • The install package is corrupt and failed the verification step.

The first case can happen if you are attempting to install the Intel XDK on an unsupported version of Windows. The Intel XDK is only supported on Microsoft Windows 7 and higher. If you attempt to install on Windows Vista (or earlier) you may see this verification error. The workaround is to install the Intel XDK on a Windows 7 or greater machine.

The second case is likely due to a corruption of the install package during download or due to tampering. The workaround is to re-download the install package and attempt another install.

If you are installing on a Windows 7 (or greater) machine and you see this message it is likely due to a missing or bad root certificate on your system. To fix this you may need to start the "Certificate Propagation" service. Open the Windows "services.msc" panel and then start the "Certificate Propagation" service. Additional links related to this problem can be found here > https://technet.microsoft.com/en-us/library/cc754841.aspx

See this forum thread for additional help regarding this issue > https://software.intel.com/en-us/forums/intel-xdk/topic/603992

Troubles installing the Intel XDK on a Linux or Ubuntu system, which option should I choose?

Choose the local user option, not root or sudo, when installing the Intel XDK on your Linux or Ubuntu system. This is the most reliable and trouble-free option and is the default installation option. This will insure that the Intel XDK has all the proper permissions necessary to execute properly on your Linux system. The Intel XDK will be installed in a subdirectory of your home (~) directory.

Inactive account/ login issue/ problem updating an APK in store, How do I request account transfer?

As of June 26, 2015 we migrated all of Intel XDK accounts to the more secure intel.com login system (the same login system you use to access this forum).

We have migrated nearly all active users to the new login system. Unfortunately, there are a few active user accounts that we could not automatically migrate to intel.com, primarily because the intel.com login system does not allow the use of some characters in userids that were allowed in the old login system.

If you have not used the Intel XDK for a long time prior to June 2015, your account may not have been automatically migrated. If you own an "inactive" account it will have to be manually migrated -- please try logging into the Intel XDK with your old userid and password, to determine if it no longer works. If you find that you cannot login to your existing Intel XDK account, and still need access to your old account, please send a message to html5tools@intel.com and include your userid and the email address associated with that userid, so we can guide you through the steps required to reactivate your old account.

Alternatively, you can create a new Intel XDK account. If you have submitted an app to the Android store from your old account you will need access to that old account to retrieve the Android signing certificates in order to upgrade that app on the Android store; in that case, send an email to html5tools@intel.com with your old account username and email and new account information.

Connection Problems? -- Intel XDK SSL certificates update

On January 26, 2016 we updated the SSL certificates on our back-end systems to SHA2 certificates. The existing certificates were due to expire in February of 2016. We have also disabled support for obsolete protocols.

If you are experiencing persistent connection issues (since Jan 26, 2016), please post a problem report on the forum and include in your problem report:

  • the operation that failed
  • the version of your XDK
  • the version of your operating system
  • your geographic region
  • and a screen capture

How do I resolve build failure: "libpng error: Not a PNG file"?  

f you are experiencing build failures with CLI 5 Android builds, and the detailed error log includes a message similar to the following:

Execution failed for task ':mergeArmv7ReleaseResources'.> Error: Failed to run command: /Developer/android-sdk-linux/build-tools/22.0.1/aapt s -i .../platforms/android/res/drawable-land-hdpi/screen.png -o .../platforms/android/build/intermediates/res/armv7/release/drawable-land-hdpi-v4/screen.png

Error Code: 42

Output: libpng error: Not a PNG file

You need to change the format of your icon and/or splash screen images to PNG format.

The error message refers to a file named "screen.png" -- which is what each of your splash screens were renamed to before they were moved into the build project resource directories. Unfortunately, JPG images were supplied for use as splash screen images, not PNG images. So the files were renamed and found by the build system to be invalid.

Convert your splash screen images to PNG format. Renaming JPG images to PNG will not work! You must convert your JPG images into PNG format images using an appropriate image editing tool. The Intel XDK does not provide any such conversion tool.

Beginning with Cordova CLI 5, all icons and splash screen images must be supplied in PNG format. This applies to all supported platforms. This is an undocumented "new feature" of the Cordova CLI 5 build system that was implemented by the Apache Cordova project.

Why do I get a "Parse Error" when I try to install my built APK on my Android device?

Because you have built an "unsigned" Android APK. You must click the "signed" box in the Android Build Settings section of the Projects tab if you want to install an APK on your device. The only reason you would choose to create an "unsigned" APK is if you need to sign it manually. This is very rare and not the normal situation.

My converted legacy keystore does not work. Google Play is rejecting my updated app.

The keystore you converted when you updated to 3088 (now 3240 or later) is the same keystore you were using in 2893. When you upgraded to 3088 (or later) and "converted" your legacy keystore, you re-signed and renamed your legacy keystore and it was transferred into a database to be used with the Intel XDK certificate management tool. It is still the same keystore, but with an alias name and password assigned by you and accessible directly by you through the Intel XDK.

If you kept the converted legacy keystore in your account following the conversion you can download that keystore from the Intel XDK for safe keeping (do not delete it from your account or from your system). Make sure you keep track of the new password(s) you assigned to the converted keystore.

There are two problems we have experienced with converted legacy keystores at the time of the 3088 release (April, 2016):

  • Using foreign (non-ASCII) characters in the new alias name and passwords were being corrupted.
  • Final signing of your APK by the build system was being done with RSA256 rather than SHA1.

Both of the above items have been resolved and should no longer be an issue.

If you are currently unable to complete a build with your converted legacy keystore (i.e., builds fail when you use the converted legacy keystore but they succeed when you use a new keystore) the first bullet above is likely the reason your converted keystore is not working. In that case we can reset your converted keystore and give you the option to convert it again. You do this by requesting that your legacy keystore be "reset" by filling out this form. For 100% surety during that second conversion, use only 7-bit ASCII characters in the alias name you assign and for the password(s) you assign.

IMPORTANT: using the legacy certificate to build your Android app is ONLY necessary if you have already published an app to an Android store and need to update that app. If you have never published an app to an Android store using the legacy certificate you do not need to concern yourself with resetting and reconverting your legacy keystore. It is easier, in that case, to create a new Android keystore and use that new keystore.

If you ARE able to successfully build your app with the converted legacy keystore, but your updated app (in the Google store) does not install on some older Android 4.x devices (typically a subset of Android 4.0-4.2 devices), the second bullet cited above is likely the reason for the problem. The solution, in that case, is to rebuild your app and resubmit it to the store (that problem was a build-system problem that has been resolved).

How can I have others beta test my app using Intel App Preview?

Apps that you sync to your Intel XDK account, using the Test tab's green "Push Files" button, can only be accessed by logging into Intel App Preview with the same Intel XDK account credentials that you used to push the files to the cloud. In other words, you can only download and run your app for testing with Intel App Preview if you log into the same account that you used to upload that test app. This restriction applies to downloading your app into Intel App Preview via the "Server Apps" tab, at the bottom of the Intel App Preview screen, or by scanning the QR code displayed on the Intel XDK Test tab using the camera icon in the upper right corner of Intel App Preview.

If you want to allow others to test your app, using Intel App Preview, it means you must use one of two options:

  • give them your Intel XDK userid and password
  • create an Intel XDK "test account" and provide your testers with that userid and password

For security sake, we highly recommend you use the second option (create an Intel XDK "test account"). 

A "test account" is simply a second Intel XDK account that you do not plan to use for development or builds. Do not use the same email address for your "test account" as you are using for your main development account. You should use a "throw away" email address for that "test account" (an email address that you do not care about).

Assuming you have created an Intel XDK "test account" and have instructed your testers to download and install Intel App Preview; have provided them with your "test account" userid and password; and you are ready to have them test:

  • sign out of your Intel XDK "development account" (using the little "man" icon in the upper right)
  • sign into your "test account" (again, using the little "man" icon in the Intel XDK toolbar)
  • make sure you have selected the project that you want users to test, on the Projects tab
  • goto the Test tab
  • make sure "MOBILE" is selected (upper left of the Test tab)
  • push the green "PUSH FILES" button on the Test tab
  • log out of your "test account"
  • log into your development account

Then, tell your beta testers to log into Intel App Preview with your "test account" credentials and instruct them to choose the "Server Apps" tab at the bottom of the Intel App Preview screen. From there they should see the name of the app you synced using the Test tab and can simply start it by touching the app name (followed by the big blue and white "Launch This App" button). Staring the app this way is actually easier than sending them a copy of the QR code. The QR code is very dense and is hard to read with some devices, dependent on the quality of the camera in their device.

Note that when running your test app inside of Intel App Preview they cannot test any features associated with third-party plugins, only core Cordova plugins. Thus, you need to insure that those parts of your apps that depend on non-core Cordova plugins have been disabled or have exception handlers to prevent your app from either crashing or freezing.

I'm having trouble making Google Maps work with my Intel XDK app. What can I do?

There are many reasons that can cause your attempt to use Google Maps to fail. Mostly it is due to the fact that you need to download the Google Maps API (JavaScript library) at runtime to make things work. However, there is no guarantee that you will have a good network connection, so if you do it the way you are used to doing it, in a browser...

<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=true"></script>

...you may get yourself into trouble, in an Intel XDK Cordova app. See Loading Google Maps in Cordova the Right Way for an excellent tutorial on why this is a problem and how to deal with it. Also, it may help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, especially item #3, to get a better understanding of why you shouldn't use the "browser technique" you're familiar with.

An alternative is to use a mapping tool that allows you to include the JavaScript directly in your app, rather than downloading it over the network each time your app starts. Several Intel XDK developers have reported very good luck with the open-source JavaScript library named LeafletJS that uses OpenStreet as it's map database source.

You can also search the Cordova Plugin Database for Cordova plugins that implement mapping features, in some cases using native SDKs and libraries.

How do I fix "Cannot find the Intel XDK. Make sure your device and intel XDK are on the same wireless network." error messages?

You can either disable your firewall or allow access through the firewall for the Intel XDK. To allow access through the Windows firewall goto the Windows Control Panel and search for the Firewall (Control Panel > System and Security > Windows Firewall > Allowed Apps) and enable Node Webkit (nw or nw.exe) through the firewall

See the image below (this image is from a Windows 8.1 system).

Google Services needs my SHA1 fingerprint. Where do I get my app's SHA fingerprint?

Your app's SHA fingerprint is part of your build signing certificate. Specifically, it is part of the signing certificate that you used to build your app. The Intel XDK provides a way to download your build certificates directly from within the Intel XDK application (see the Intel XDK documentation for details on how to manage your build certificates). Once you have downloaded your build certificate you can use these instructions provided by Google, to extract the fingerprint, or simply search the Internet for "extract fingerprint from android build certificate" to find many articles detailing this process.

Why am I unable to test or build or connect to the old build server with Intel XDK version 2893?

This is an Important Note Regarding the use of Intel XDK Versions 2893 and Older!!

As of June 13, 2016, versions of the Intel XDK released prior to March 2016 (2893 and older) can no longer use the Build tab, the Test tab or Intel App Preview; and can no longer create custom debug modules for use with the Debug and Profile tabs. This change was necessary to improve the security and performance of our Intel XDK cloud-based build system. If you are using version 2893 or older, of the Intel XDK, you must upgrade to version 3088 or greater to continue to develop, debug and build Intel XDK Cordova apps.

The error message you see below, "NOTICE: Internet Connection and Login Required," when trying to use the Build tab is due to the fact that the cloud-based component that was used by those older versions of the Intel XDK work has been retired and is no longer present. The error message appears to be misleading, but is the easiest way to identify this condition. 

How do I run the Intel XDK on Fedora Linux?

See the instructions below, copied from this forum post:

$ sudo find xdk/install/dir -name libudev.so.0
$ cd dir/found/above
$ sudo rm libudev.so.0
$ sudo ln -s /lib64/libudev.so.1 libudev.so.0

Note the "xdk/install/dir" is the name of the directory where you installed the Intel XDK. This might be "/opt/intel/xdk" or "~/intel/xdk" or something similar. Since the Linux install is flexible regarding the precise installation location you may have to search to find it on your system.

Once you find that libudev.so file in the Intel XDK install directory you must "cd" to that directory to finish the operations as written above.

Additional instructions have been provided in the related forum thread; please see that thread for the latest information regarding hints on how to make the Intel XDK run on a Fedora Linux system.

Back to FAQs Main

Robotics Development Kit Blink LED Tutorial

$
0
0

Driving the GPIO Pins on the UP Board of the Intel® RealSense™ Robotics Development Kit to blink a LED circuit.

What you will learn

This tutorial sets out to demonstrate a basic usage of the GPIO pins by appealing to the classic electronic analogy for “Hello World”, which entails setting up the UP Board to make an external LED blink.

Introduction to the Robotics Development Kit UP Board

The Intel® RealSense™ Robotics Development Kit (RDK) is comprised of the Intel® RealSense™ R200 depth-camera (R200) and the Aaeon* UP Board. The computing heart of the system, the UP Board, is capable of connectivity to the outside world via a 40-pin input/output header as shown in Figure 1. The UP Board has a total of 28 independent GPIO pins that are provided on the I/O header. Ubuntu 14.04 has kernel platform drivers developed for the UP board to provide Linux GPIO pin numbering in the range 0-27, emulating that of the Raspberry Pi. 

Access to the hardware GPIOs for this tutorial will be done at a low level using Linux sysfs.  Sysfs provides a way in Linux for users (or code in the user-space) to interact with devices at the system (kernel) level.

This tutorial requires no special libraries since it uses the sysfs interface.

Important: Please note that the Linux GPIO numbers in Figure 1 are different from both the physical pin numbers and the UP Board pinout. The Linux GPIO numbers are assigned to match the Raspberry Pi BCM GPIO numbering scheme.

For comparison with Raspberry Pi layouts, visit: http://pinout.xyz

Lighting up a LED Using Your UP Board

Once you have configured the UP Board of the RDK according to the quickstart guide From Zero to Hero: Getting up and running with the Intel RealSense Robotic Development Kityou are ready for your first real project. We will light up a LED using the C programming language and the GPIO pins on your UP board.

What You Will Learn

  • You will construct a basic electrical circuit and attach it to your UP Board GPIO pins

What You Will Need

  • 1 - small LED, any color
  • 1 - 50 ohm resistor
  • Some small-gauge solid core wire
  • Breadboard or alligator clips, or both, to hold connections

Let There Be Light

Before we get around to writing any code, let's first get acquainted with the pin numbering of our UP Board and create a simple circuit. We'll start by simply lighting our led using the 3.3v pin and the ground pin on our UP Board. We will use the following schematic for our circuit:


Figure 2

Before starting, unplug your UP Board. You wouldn't want to risk shorting it out while working with it 'powered on', especially since this is our first project.

  • Using your assortment of materials, create the circuit on either your breadboard, or using your alligator clips.
  • Pin 1 (+3.3 volts) should go to the longer leg of your LED (anode). This pin provides a steady supply of 3.3v. Unlike the GPIO pins on your UP Board, this pin is not programmable, and cannot be controlLED by software.
  • Attach the shorter leg of the LED to the resistor. Finally, attach the other end of the resistor to Pin 6 (- ground) on your UP Board.

Double-check your connections. When you are done, your circuit should look like this:


Figure 3

Power on your UP Board - the LED should immediately turn on.

Controlling the LED with Code

Now that we've tested our basic circuit, it's time to move the positive lead from the 'always on' 3.3v pin to one of the programmable GPIO pins. Here is what our circuit will look like:


Figure 4

  • Power-off your UP Board again before making any changes to your wiring.
  • Move the positive lead from pin 1 to pin 7.

When you are done, your circuit should look like this:


Figure 5

Source to Drive Blink

Below is a code sample that will drive to blink the circuit you have built thus far.

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define IN   0
#define OUT  1

#define LOW  0
#define HIGH 1

#define PIN  24 /* physical pin 18 */
#define POUT 4  /* physical pin 7  */

static int GPIOExport(int pin);
static int GPIOUnexport(int pin);
static int GPIODirection(int pin, int dir);
static int GPIORead(int pin);
static int GPIOWrite(int pin, int value);

int main(int argc, char *argv[])
{
	int repeat = 9;

	/*
	 * Enable GPIO pins
	 */
	if (-1 == GPIOExport(POUT) || -1 == GPIOExport(PIN))
		return(1);

	/*
	 * Set GPIO directions
	 */
	if (-1 == GPIODirection(POUT, OUT) || -1 == GPIODirection(PIN, IN))
		return(2);

	do {
		/*
		 * Write GPIO value
		 */
		if (-1 == GPIOWrite(POUT, repeat % 2))
			return(3);

		/*
		 * Read GPIO value
		 */
		printf("I'm reading %d in GPIO %d\n", GPIORead(PIN), PIN);

		usleep(500 * 1000);
	}
	while (repeat--);

	/*
	 * Disable GPIO pins
	 */
	if (-1 == GPIOUnexport(POUT) || -1 == GPIOUnexport(PIN))
		return(4);

	return(0);
}

Int GPIOExport(int pin)
{
#define BUFFER_MAX 3
	char buffer[BUFFER_MAX];
	ssize_t bytes_written;
	int fd;

	fd = open("/sys/class/gpio/export", O_WRONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open export for writing!\n");
		return(-1);
	}

	bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
	write(fd, buffer, bytes_written);
	close(fd);
	return(0);
}

Int GPIOUnexport(int pin)
{
	char buffer[BUFFER_MAX];
	ssize_t bytes_written;
	int fd;

	fd = open("/sys/class/gpio/unexport", O_WRONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open unexport for writing!\n");
		return(-1);
	}

	bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
	write(fd, buffer, bytes_written);
	close(fd);
	return(0);
}

Int GPIODirection(int pin, int dir)
{
	static const char s_directions_str[]  = "in\0out";

#define DIRECTION_MAX 35
	char path[DIRECTION_MAX];
	int fd;

	snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
	fd = open(path, O_WRONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open gpio direction for writing!\n");
		return(-1);
	}

	if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) {
		fprintf(stderr, "Failed to set direction!\n");
		return(-1);
	}

	close(fd);
	return(0);
}

Int GPIORead(int pin)
{
#define VALUE_MAX 30
	char path[VALUE_MAX];
	char value_str[3];
	int fd;

	snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
	fd = open(path, O_RDONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open gpio value for reading!\n");
		return(-1);
	}

	if (-1 == read(fd, value_str, 3)) {
		fprintf(stderr, "Failed to read value!\n");
		return(-1);
	}

	close(fd);

	return(atoi(value_str));
}

Int GPIOWrite(int pin, int value)
{
	static const char s_values_str[] = "01";

	char path[VALUE_MAX];
	int fd;

	snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
	fd = open(path, O_WRONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open gpio value for writing!\n");
		return(-1);
	}

	if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) {
		fprintf(stderr, "Failed to write value!\n");
		return(-1);
	}

	close(fd);
	return(0);
}

If you have the source code into a file named blink.c you can compile it using the following command-line command:

gcc –Wall –o blink blink.c

Conclusion

This UP Board tutorial sets out to present a “Hello World” circuit that enables the UP Board to a C program using the Linux sysfs mechanism to drive a LED to blink on-off for 10 times.

The next tutorial in this series will drive the brightness of the LED by incorporating depth-data coming from the R200 camera and the Intel® RealSense™ Cross Platform API, and modifying both the circuit and the C program to accomplish this task.

Intel Inside. Software Optimization Outside on the Intel® Xeon Phi™ Product Family

$
0
0

Experts from Allinea, Altair, Convergent Science, and Kitware share some of the use cases and explore the significant advantages of running their applications on the Intel® Xeon Phi™ product family.

  • David DeMarle (R&D Engineer, Kitware, Inc.) speaks on the engineering advantages of the Intel® Xeon Phi™ product family. View video

  • Allinea CEO David Lecomber addresses the potential of fully using core capacity with the Intel® Xeon Phi™ product family. View video

  • Convergent Science’s Rob Kaczmarek shares the innovation potential enabled by the Intel® Xeon Phi™ product family. View video

  • Altair’s Scott Scuhyta talks about the competitive advantages enabled by the Intel® Xeon Phi™ product family. View video

  • LSTC’s Brian Wainscott shares prototyping performance gains made possible by the Intel® Xeon Phi™ product family. View video

     

 

Intel Continues Quest for New Talent, as SMU Guildhall Dazzles With Fire and Ice

$
0
0

Download PDF [PDF 1 MB]

Imagine that you are Kaya, a young woman of the northern tribe. Your people worship the nature goddess but, having fallen out of favor with this celestial being, are now denied the sacred knowledge of fire and ice. Your task: traverse an ancient temple to learn the power of these elemental forces and show your people the ways of balance. You achieve this by reaching the highest terrace, the Elemental Temple.

This is Inua, an action-packed, first-person 3D puzzler in which players use ice and fire to manipulate their environment and confound enemies in order to progress through a mysterious sacred structure. Developed by a dedicated team of students at Southern Methodist University (SMU) Guildhall, Inua recently scooped up First Place for Best Visuals at the 2016 Intel® University Games Showcase (IUGS), highlighting the awe-inspiring possibilities when developers combine state-of-the-art hardware, stunning graphics, and some amazing creative talent.

This article details the challenging yet rewarding journey that Inua’s developers faced from concept to completion, and, eventually, the winner’s podium.

The Game’s the Thing

Held in conjunction with the Game Developers Conference (GDC), the IUGS invites representatives from the top ten academic game-developer programs to present their feats of magic to an enthusiastic audience consisting of industry professionals, fellow students, the press, and media influencers. The third annual showcase, in 2016, saw schools including Carnegie Mellon University, Drexel University, and UC Santa Cruz, among others, compete for $35,000 in hardware prizes. A panel of judges consisting of game industry luminaries picked the winners.

Led by game producer Matt Worrell, SMU Guildhall was looking to build on past triumphs, including two top-prize wins at the first IUGS in 2014. “As a team, we had several goals with Inua, but competing in the Intel University Games Showcase was our top objective,” said Worrell.

Located in Plano, Texas, SMU Guildhall features a leading-edge digital game-development program, offering specializations in art creation, level design, production, and programming. Established in 2003, the school has seen over 600 students graduate, with alumni working at more than 250 video game studios around the world.

Most years, SMU Guildhall has class sizes ranging from 40 to 50 students. But Worrell’s cohort had only twelve students, which persuaded him to augment the core group with artists from earlier cohorts. Rounding out the SMU Guildhall team was a set of talented programmers, designers, and an audio developer, together with lead designer Jon Clark. “We were Batman and Robin, me as producer and Jon as game designer,” joked Worrell.


Inua team members: (top, from left) Brian Rust, David Gautier, Jason Leary, Matt Worrell, Michael Crawford (front row, from left) Trevor Youngblood, Hoang Nguyen, Evan Kohn, Jon Clark, Laura Brothers, Taylor Smith and Amanda East.

With the team in place and ideas quickly gelling, it was time to choose a name for the group. After much discussion, they settled on ‘Betrayal Games’, taken from the board game Betrayal at House on the Hill, which the team played during lunch hours. The serious work could now start.

Growing an Idea Organically

Coming up with the game concept was the critical first step, and definitely a team effort. Every person, regardless of role, had to pitch their best idea to the team, even if they didn’t have a fully-formed proposal. Worrell said that this was to ensure that everybody felt comfortable sharing ideas and raising issues throughout the development process. As it turns out, it was Worrell’s idea that won the day, though the game he pitched was very different to what Inua ultimately became.

“My initial idea would have forced a huge animation budget that we simply couldn't afford,” recalled Worrell. But a few of the core ideas were strong enough to survive. To begin, the designers liked the idea of creating fun, interesting puzzles. In addition, everybody on the team loved the notion of incorporating the power of nature into the story narrative. And, finally, the team wanted to imbue Inua with a rich organic environment.


The Ice Trail, showcasing Inua’s amazing graphical environment.

Unlike many first-person puzzle challenges that situate players in clean, lab-like settings, with flat walls and easy-to-spot visual cues, Inua offers a deeply textured and visually complex environment full of rocks, water, ice and fire. Intricate and elaborate details, as fashioned by nature, are everywhere. With these core ideas in hand, the SMU Guildhall team readjusted to match available resources, eventually coming up with a game that resonated with everybody.

To reach the desired level of realism, the team looked to real-world examples for inspiration, focusing on dramatic environments such as Iceland, Alaska, Ireland, and Scotland. The team also became captivated by the otherworldly appearance of basalt columns, and cave rock formations that inherently project the power of nature.

At this point, the team worked together to develop a prototype to prove Inua’s technology and art style, ensuring that everyone shared a rock-solid, unified vision. With pre-production formally beginning in fall 2014, and principal development commencing the following spring, Worrell recalls experimenting with a lot of different ideas. “We didn't really settle on any one idea until late December, but when we did, we made sure that the design would present well at IUGS.”

When a good idea would materialize, the team went through a series of trials to check whether it fit the core ideas of the game, in addition to the time- and budget-constraints. This helped flesh out the mechanism to locate cues within the environment to help players navigate, and ultimately succeed at, the game. “We had to find a way to teach players about certain abilities throughout the game,” explained Worrell. “And we had to do that in a fun way.”

The process, however, wasn’t perfect. In one notable instance, the team had developed a major gear system showing the balance between the natural and the mechanical world, and how Kaya’s people could move from spiritually aligned to engineered systems. But after developing an entire level of gears and moving platforms, the team found that it simply didn’t fit thematically. Even though it was late in production, the decision was made to leave the level out.

Crafting the Product

Worrell describes the SMU Guildhall program as intense, and designed to prepare students for industry. To that end, team members had to commit to 15 hours of core development work together each week, in addition to their regular studies and exams. Not surprisingly, extra work was often necessary when approaching deadlines.

Early on, the team selected Unreal* Engine 4 as the development platform, both for its power and its prominence within the gaming industry. “The engine is fantastic,” enthused Worrell. “We knew we wanted to make a complex, beautiful environment, and Unreal Engine 4’s physics-based Material Editor was ideal for that.”

The SMU Guildhall team was equally impressed with how quickly members were able to come up to speed with the tool. “Unreal Engine 4 is basically made for everybody,” noted Worrell, pointing to the easy-to-use Blueprints system, which allows visual scripting and live debugging without the need for C++ code. Similarities with the Unreal Development Kit (UDK), which is the free edition of Unreal Engine 3, further helped smooth the transition. Likewise, the new Material Editor, enhanced with an expanded set of Gizmos, presented few unexpected issues.

Most importantly, Unreal Engine 4 allowed each team member to work to his or her particular strengths. For example, artists were able to focus on creating lighting and assets; designers could create systems; and programmers were able to integrate everything with C++ code.

There was one catch, though. Unreal Engine 4 was constantly being enhanced and updated while Inua was in development. According to Worrell, the team had to adjust to seven major updates to the system over the 18 weeks of principal development, and many more minor upgrades. This led to some challenging situations.

For instance, the team would create a system for physics-based water using Blueprints, and then, a couple of weeks later, a new update would become available with the system built-in and implemented in the engine in a significantly better way. In another case, the team had to decide between creating either transparent or bright, reflecting water; they chose the former. A later edition of the engine seamlessly provided both options. The team also had a number of issues with lighting: early on, the engine only supported one dynamic light. That changed in mid-development as well. “It was a give-and-take, developing using an engine that was itself in development,” explained Worrell. “We had to really be fluid in how we managed the process.”

Part of the solution involved adopting an agile and rapid prototyping methodology that allowed player test-results and new ideas to be quickly incorporated. This approach was particularly helpful for solving several gameplay issues. For example, at various points in the game, test players sometimes felt completely lost. “They didn’t know where they could use their powers, or how they could progress,” explained Worrell. To help players along without giving too much away, the team added something called a “spirit trail,” which is a floating particle that hovers around items that offer interaction.

At the very beginning, when players are learning the game for the first time, the spirit trail literally circles items with which players need to interact. Later in the game, however, the spirit trail simply leads players into a room, and lets them figure things out for themselves. “Through trial-and-error, we learned which play elements worked and which did not,” noted Worrell.

Teaming with Intel for Success

Intel technology played a crucial role in the success of Inua. First and foremost, the SMU Guildhall team relied heavily on a powerful set of Intel® Swarm servers to push iterations out quickly, enhancing the benefits of rapid prototyping. “We had heard horror stories that people sometimes stopped working because they didn’t want to touch their computer and risk crashing a build,” noted Worrell. Not so with the Intel® Swarm servers. The team was able to push builds within an hour, early in the development cycle. Even later, with a much bigger game to build, the process only took two or three hours.


Inua presentation at the 2016 IUGS: (from left to right) Taylor Smith, Jon Clark, and Matt Worrell.

The team also benefited from using an Intel-supplied laptop computer, offered to every team for testing as part of the competition. Pushing Unreal Engine 4 to the max, Worrell quietly confessed that the team had spent little time optimizing. When it came time to test on the laptop, the team didn’t know what to expect. “We were shocked,” admitted Worrell. In fact, the team didn’t need to create a separate build or make any adjustments to have the game work on the Intel machine. “It was able to handle whatever we threw at it,” Worrell went on. “And that’s partly because of the awesome integrated Intel graphics in the laptop."

“The Intel folks were a great group of people who answered all our questions quickly,” said Worrell. “There were so many amazing games in the competition, and thanks to all the organization and help, we were able to offer a smashing presentation.”

Looking Forward

For SMU Guildhall, winning the Best Visuals category was incredibly rewarding. “Visuals are what we hung our hat on, and so that meant a lot to the team,” said Worrell. The future of Inua is less certain, though, since much of the team has already moved on to new projects. Worrell has reason to be optimistic, however. Two games made at SMU Guildhall last fall–Gravitas (a game on which Worrell also worked) and Scrapped–have both been greenlit by the Steam* online gaming community, and will be available in the Steam Community Market. Worrell hopes to be able to do something similar with Inua.

Another option is to port Inua to one or more console platforms, such as Playstation* or Xbox*–the game plays very well using a console controller, according to Worrell. The good news is that SMU Guildhall makes it easy for team members to monetize their work. As long as the entire team agrees, the university presents no obstacles to the team taking over the intellectual property. “Guildhall wants you to succeed and do well with your game,” explained Worrell. “It's something that we might choose to do with Inua.” Launching a Kickstarter campaign is another option that Worrell might consider.

In the meantime, Worrell encourages people to keep an eye on SMU Guildhall. “There are super-talented and creative people there, producing some very unique and awesome games.”

SIDEBAR

Tips From the Inua Team for Creating an Award-Winning Game

  • Engage all members of your team from the start to encourage idea-sharing and prompt issue resolution.
  • Choose a distinctive feature (an organically-complex visual environment in the case of Inua) to differentiate your game from others.
  • Ensure that new ideas integrate well with the core of your game, and be prepared to cut content that does not fit thematically.
  • Choose a suitable development environment to match the needs of your game (Unreal Engine 4 for Inua), but understand that environments are dynamic and get updated with new capabilities regularly.
  • Adopt a rapid development methodology (Inua builds ran on Intel Swarm servers for speedy turnaround) and test frequently to solve any gameplay issues early.

Resources

Intel University Games Showcase 2016 Overview

Intel University Games Showcase 2016 Results

SMU Guildhall Web Site

Unreal Engine 4 Documentation

API without Secrets: Introduction to Vulkan* Part 4

$
0
0

Download  [PDF 890KB]

Link to Github Sample Code


Go to: API without Secrets: Introduction to Vulkan* Part 3: First Triangle


Table of Contents

Tutorial 4: Vertex Attributes – Buffers, Images, and Fences

Tutorial 4: Vertex Attributes – Buffers, Images, and Fences

In previous tutorials we learned the basics. The tutorials themselves were long and (I hope) detailed enough. This is because the learning curve of a Vulkan* API is quite steep. And, as you can see, a considerable amount of knowledge is necessary to prepare even the simplest application.

But now we can build on these foundations. So the tutorials will be shorter and focus on smaller topics related to a Vulkan API. In this part I present the recommended way of drawing arbitrary geometry by providing vertex attributes through vertex buffers. As the code of this lesson is similar to the code from the “03 – First Triangle” tutorial, I focus on and describe only the parts that are different.

I also show a different way of organizing the rendering code. Previously we recorded command buffers before the main rendering loop. But in real-life situations, every frame of animation is different, so we can’t prerecord all the rendering commands. We should record and submit the command buffer as late as possible to minimize input lag and acquire as recent input data as possible. We will record the command buffer just before it is submitted to the queue. But a single command buffer isn’t enough. We should not record the same command buffer until the graphics card finishes processing it after it was submitted. This moment is signaled through a fence. But waiting on a fence every frame is a waste of time, so we need more command buffers used interchangeably. With more command buffers, more fences are also needed and the situation gets more complicated. This tutorial shows how to organize the code so it is easily maintained, flexible, and as fast as possible.

Specifying Render Pass Dependencies

We start by creating a render pass, in the same way as the previous tutorial. But this time we will provide additional information. Render pass describes the internal organization of rendering resources (images/attachments), how they are used, and how they change during the rendering process. Images’ layout changes can be performed explicitly by creating image memory barriers. But they can also be performed implicitly, when proper render pass description is specified (initial, subpass, and final image layouts). Implicit transition is preferred, as drivers can perform such transitions more optimally.

In this part of tutorial, identically as in the previous part, we specify “transfer src” for initial and final image layouts, and “color attachment optimal” subpass layout for our render pass. But previous tutorials lacked important, additional information, specifically how the image was used (that is, what types of operations occurred in connection with an image), and when it was used (which parts of a rendering pipeline were using an image). This information can be specified both in the image memory barrier and the render pass description. When we create an image memory barrier, we specify the types of operations which concern the given image (memory access types before and after barrier), and we also specify when this barrier should be placed (pipeline stages in which image was used before and after the barrier).

When we create a render pass and provide a description for it, the same information is specified through subpass dependencies. This additional data is crucial for a driver to optimally prepare an implicit barrier. Below is the source code that creates a render pass and prepares subpass dependencies.

std::vector<VkSubpassDependency> dependencies = {
  {
    VK_SUBPASS_EXTERNAL,                            // uint32_t                       srcSubpass
    0,                                              // uint32_t                       dstSubpass
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,           // VkPipelineStageFlags           srcStageMask
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // VkPipelineStageFlags           dstStageMask
    VK_ACCESS_MEMORY_READ_BIT,                      // VkAccessFlags                  srcAccessMask
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                  dstAccessMask
    VK_DEPENDENCY_BY_REGION_BIT                     // VkDependencyFlags              dependencyFlags
  },
  {
    0,                                              // uint32_t                       srcSubpass
    VK_SUBPASS_EXTERNAL,                            // uint32_t                       dstSubpass
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // VkPipelineStageFlags           srcStageMask
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,           // VkPipelineStageFlags           dstStageMask
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                  srcAccessMask
    VK_ACCESS_MEMORY_READ_BIT,                      // VkAccessFlags                  dstAccessMask
    VK_DEPENDENCY_BY_REGION_BIT                     // VkDependencyFlags              dependencyFlags
  }
};

VkRenderPassCreateInfo render_pass_create_info = {
  VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,        // VkStructureType                sType
  nullptr,                                          // const void                    *pNext
  0,                                                // VkRenderPassCreateFlags        flags
  1,                                                // uint32_t                       attachmentCount
  attachment_descriptions,                          // const VkAttachmentDescription *pAttachments
  1,                                                // uint32_t                       subpassCount
  subpass_descriptions,                             // const VkSubpassDescription    *pSubpasses
  static_cast<uint32_t>(dependencies.size()),       // uint32_t                       dependencyCount&dependencies[0]                                  // const VkSubpassDependency     *pDependencies
};

if( vkCreateRenderPass( GetDevice(), &render_pass_create_info, nullptr, &Vulkan.RenderPass ) != VK_SUCCESS ) {
  std::cout << "Could not create render pass!"<< std::endl;
  return false;
}

1.Tutorial04.cpp, function CreateRenderPass()

Subpass dependencies describe dependencies between different subpasses. When an attachment is used in one specific way in a given subpass (for example, rendering into it), but in another way in another subpass (sampling from it), we can create a memory barrier or we can provide a subpass dependency that describes the intended usage of an attachment in these two subpasses. Of course, the latter option is recommended, as the driver can (usually) prepare the barriers in a more optimal way. And the code itself is improved—everything required to understand the code is gathered in one place, one object.

In our simple example, we have only one subpass, but we specify two dependencies. This is because we can (and should) specify dependencies between render passes (by providing the number of a given subpass) and operations outside of them (by providing a VK_SUBPASS_EXTERNAL value). Here we provide one dependency for color attachment between operations occurring before a render pass and its only subpass. The second dependency is defined for operations occurring inside a subpass and after the render pass.

What operations are we talking about? We are using only one attachment, which is an image acquired from a presentation engine (swapchain). The presentation engine uses an image as a source of a presentable data. It only displays an image. So the only operation that involves this image is “memory read” on the image with “present src” layout. This operation doesn’t occur in any normal pipeline stage, but it can be represented in the “bottom of pipeline” stage.

Inside our render pass, in its only subpass (with index 0), we are rendering into an image used as a color attachment. So the operation that occurs on this image is “color attachment write”, which is performed in the “color attachment output” pipeline stage (after a fragment shader). After that the image is presented and returned to a presentation engine, which again uses this image as a source of data. So, in our example, the operation after the render pass is the same as before it: “memory read”.

We specify this data through an array of VkSubpassDependency members. And when we create a render pass and a VkRenderPassCreateInfo structure, we specify the number of elements in the dependencies array (through dependencyCount member), and provide an address of its first element (through pDependencies). In a previous part of the tutorial we have provided 0 and nullptr for these two fields. VkSubpassDependency structure contains the following fields:

  • srcSubpass – Index of a first (previous) subpass or VK_SUBPASS_EXTERNAL if we want to indicate dependency between subpass and operations outside of a render pass.
  • dstSubpass – Index of a second (later) subpass (or VK_SUBPASS_EXTERNAL).
  • srcStageMask – Pipeline stage during which a given attachment was used before (in a src subpass).
  • dstStageMask – Pipeline stage during which a given attachment will be used later (in a dst subpass).
  • srcAccessMask – Types of memory operations that occurred in a src subpass or before a render pass.
  • dstAccessMask – Types of memory operations that occurred in a dst subpass or after a render pass.
  • dependencyFlags – Flag describing the type (region) of dependency.

Graphics Pipeline Creation

Now we will create a graphics pipeline object. (We should create framebuffers for our swapchain images, but we will do that during command buffer recording). We don’t want to render a geometry that is hardcoded into a shader. We want to draw any number of vertices, and we also want to provide additional attributes, not only vertex positions. What should we do first?

Writing Shaders

First have a look at the vertex shader written in GLSL code:

#version 450

layout(location = 0) in vec4 i_Position;
layout(location = 1) in vec4 i_Color;

out gl_PerVertex
{
  vec4 gl_Position;
};

layout(location = 0) out vec4 v_Color;

void main() {
    gl_Position = i_Position;
    v_Color = i_Color;
}

2.shader.vert

This shader is quite simple, though more complicated than the one from Tutorial 03.

We specify two input attributes (named i_Position and i_Color). In Vulkan, all attributes must have a location layout qualifier. When we specify a description of the vertex attributes in Vulkan API, the names of these attributes don’t matter, only their indices/locations. In OpenGL* we could ask for a location of an attribute with a given name. In Vulkan we can’t do this. Location layout qualifiers are the only way to go.

Next, we redeclare the gl_PerVertex block in the shader. Vulkan uses shader I/O blocks, and we should redeclare a gl_PerVertex block to specify exactly what members of this block to use. When we don’t, the default definition is used. But we must remember that the default definition contains gl_ClipDistance[], which requires us to enable a feature named shaderClipDistance (and in Vulkan we can’t use features that are not enabled during device creation or our application may not work correctly). Here we are using only a gl_Position member so the feature is not required.

We then specify an additional output varying variable called v_Color in which we store vertices’ colors. Inside a main function we copy values provided by an application to proper output variables: position to gl_Position and color to v_Color.

Now look at a fragment shader to see how attributes are consumed.

#version 450

layout(location = 0) in vec4 v_Color;

layout(location = 0) out vec4 o_Color;

void main() {
  o_Color = v_Color;
}

3.shader.frag

In a fragment shader, the input varying variable v_Color is copied to the only output variable called o_Color. Both variables have location layout specifiers. The v_Color variable has the same location as the output variable in the vertex shader, so it will contain color values interpolated between vertices.

These shaders can be converted to a SPIR-V assembly the same way as previously. The following commands do this:

glslangValidator.exe -V -H shader.vert > vert.spv.txt

glslangValidator.exe -V -H shader.frag > frag.spv.txt

So now, when we know what attributes we want to use in our shaders, we can create the appropriate graphics pipeline.

Vertex Attributes Specification

The most important improvement in this tutorial is added to the vertex input state creation, for which we specify a variable of type VkPipelineVertexInputStateCreateInfo. In this variable we provide pointers to structures, which define the type of vertex input data and number and layout of our attributes.

We want to use two attributes: vertex positions, which are composed of four float components, and vertex colors, which are also composed of four float values. We will lay all of our vertex data in one buffer using the interleaved attributes layout. This means that position for the first vertex will be placed, next color for the same vertex, next the position of second vertex, after that the color of the second vertex, then position and color of third vertex and so on. All this specification is performed with the following code:

std::vector<VkVertexInputBindingDescription> vertex_binding_descriptions = {
  {
    0,                                                          // uint32_t                                       binding
    sizeof(VertexData),                                         // uint32_t                                       stride
    VK_VERTEX_INPUT_RATE_VERTEX                                 // VkVertexInputRate                              inputRate
  }
};

std::vector<VkVertexInputAttributeDescription> vertex_attribute_descriptions = {
  {
    0,                                                          // uint32_t                                       location
    vertex_binding_descriptions[0].binding,                     // uint32_t                                       binding
    VK_FORMAT_R32G32B32A32_SFLOAT,                              // VkFormat                                       format
    offsetof(struct VertexData, x)                              // uint32_t                                       offset
  },
  {
    1,                                                          // uint32_t                                       location
    vertex_binding_descriptions[0].binding,                     // uint32_t                                       binding
    VK_FORMAT_R32G32B32A32_SFLOAT,                              // VkFormat                                       format
    offsetof( struct VertexData, r )                            // uint32_t                                       offset
  }
};

VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = {
  VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,    // VkStructureType                                sType
  nullptr,                                                      // const void                                    *pNext
  0,                                                            // VkPipelineVertexInputStateCreateFlags          flags;
  static_cast<uint32_t>(vertex_binding_descriptions.size()),    // uint32_t                                       vertexBindingDescriptionCount&vertex_binding_descriptions[0],                              // const VkVertexInputBindingDescription         *pVertexBindingDescriptions
  static_cast<uint32_t>(vertex_attribute_descriptions.size()),  // uint32_t                                       vertexAttributeDescriptionCount&vertex_attribute_descriptions[0]                             // const VkVertexInputAttributeDescription       *pVertexAttributeDescriptions
};

4.Tutorial04.cpp, function CreatePipeline()

First specify the binding (general memory information) of vertex data through VkVertexInputBindingDescription. It contains the following fields:

  • binding – Index of a binding with which vertex data will be associated.
  • stride – The distance in bytes between two consecutive elements (the same attribute for two neighbor vertices).
  • inputRate – Defines how data should be consumed, per vertex or per instance.

The stride and inputRate fields are quite self-explanatory. Additional information may be required for a binding member. When we create a vertex buffer, we bind it to a chosen slot before rendering operations. The slot number (an index) is this binding and here we describe how data in this slot is aligned in memory and how it should be consumed (per vertex or per instance). Different vertex buffers can be bound to different bindings. And each binding may be differently positioned in memory.

Next step is to define all vertex attributes. We must specify a location (index) for each attribute (the same as in a shader source code, in location layout qualifier), source of data (binding from which data will be read), format (data type and number of components), and offset at which data for this specific attribute can be found (offset from the beginning of a data for a given vertex, not from the beginning of all vertex data). The situation here is exactly the same as in OpenGL where we created Vertex Buffer Objects (VBO, which can be thought of as an equivalent of “binding”) and defined attributes using glVertexAttribPointer() function through which we specified an index of an attribute (location), size and type (number of components and format), stride and offset. This information is provided through the VkVertexInputAttributeDescription structure. It contains these fields:

  • location – Index of an attribute, the same as defined by the location layout specifier in a shader source code.
  • binding – The number of the slot from which data should be read (source of data like VBO in OpenGL), the same binding as in a VkVertexInputBindingDescription structure and vkCmdBindVertexBuffers() function (described later).
  • format – Data type and number of components per attribute.
  • offset – Beginning of data for a given attribute.

When we are ready, we can prepare vertex input state description by filling a variable of type VkPipelineVertexInputStateCreateInfo which consist of the following fields:

  • sType – Type of structure, here it should be equal to VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO.
  • pNext – Pointer reserved for extensions. Right now set this value to null.
  • flags – Parameter reserved for future use.
  • vertexBindingDescriptionCount – Number of elements in the pVertexBindingDescriptions array.
  • pVertexBindingDescriptions – Array describing all bindings defined for a given pipeline (buffers from which values of all attributes are read).
  • vertexAttributeDescriptionCount – Number of elements in the pVertexAttributeDescriptions array.
  • pVertexAttributeDescriptions – Array with elements specifying all vertex attributes.

This concludes vertex attributes specification at pipeline creation. But to use them, we must create a vertex buffer and bind it to command buffer before we issue a rendering command.

Input Assembly State Specification

Previously we have drawn a single triangle using a triangle list topology. Now we will draw a quad, which is more convenient to draw by defining just four vertices, not two triangles and six vertices. To do this, we must use triangle strip topology. We define it through VkPipelineInputAssemblyStateCreateInfo structure that has the following members:

  • sType – Structure type, here equal to VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO.
  • pNext – Pointer reserved for extensions.
  • flags – Parameter reserved for future use.
  • topology – Topology used for drawing vertices (like triangle fan, strip, list).
  • primitiveRestartEnable – Parameter defining whether we want to restart assembling a primitive by using a special value of vertex index.

Here is the code sample used to define triangle strip topology:

VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = {
  VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,  // VkStructureType                                sType
  nullptr,                                                      // const void                                    *pNext
  0,                                                            // VkPipelineInputAssemblyStateCreateFlags        flags
  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                         // VkPrimitiveTopology                            topology
  VK_FALSE                                                      // VkBool32                                       primitiveRestartEnable
};

5.Tutorial04.cpp, function CreatePipeline()

Viewport State Specification

In this tutorial we introduce another change. Previously, for the sake of simplicity, we have hardcoded the viewport and scissor test parameters, which unfortunately caused our image to be always the same size, no matter how big the application window was. This time, we won’t specify these values through the VkPipelineViewportStateCreateInfo structure. We will use a dynamic state for that. Here is a code responsible for defining static viewport state parameters:

VkPipelineViewportStateCreateInfo viewport_state_create_info = {
  VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,        // VkStructureType                                sType
  nullptr,                                                      // const void                                    *pNext
  0,                                                            // VkPipelineViewportStateCreateFlags             flags
  1,                                                            // uint32_t                                       viewportCount
  nullptr,                                                      // const VkViewport                              *pViewports
  1,                                                            // uint32_t                                       scissorCount
  nullptr                                                       // const VkRect2D                                *pScissors
};

6.Tutorial04.cpp, function CreatePipeline()

The structure that defines static viewport parameters has the following members:

  • sType – Type of the structure, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO here.
  • pNext – Pointer reserved for extension-specific parameters.
  • flags – Parameter reserved for future use.
  • viewportCount – Number of viewports.
  • pViewports – Pointer to a structure defining static viewport parameters.
  • scissorCount – Number of scissor rectangles (must have the same value as viewportCount parameter).
  • pScissors – Pointer to an array of 2D rectangles defining static scissor test parameters for each viewport.

When we want to define viewport and scissor parameters through a dynamic state, we don’t have to fill pViewports and pScissors members. That’s why they are set to null in the example above. But, we always have to define the number of viewports and scissor test rectangles. These values are always specified through the VkPipelineViewportStateCreateInfo structure, no matter if we want to use dynamic or static viewport and scissor state.

Dynamic State Specification

When we create a pipeline, we can specify which parts of it are always static, defined through structures at a pipeline creation, and which are dynamic, specified by proper function calls during command buffer recording. This allows us to lower the number of pipeline objects that differ only with small details like line widths, blend constants, or stencil parameters, or mentioned viewport size. Here is the code used to define parts of pipeline that should be dynamic:

std::vector<VkDynamicState> dynamic_states = {
  VK_DYNAMIC_STATE_VIEWPORT,
  VK_DYNAMIC_STATE_SCISSOR,
};

VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {
  VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,         // VkStructureType                                sType
  nullptr,                                                      // const void                                    *pNext
  0,                                                            // VkPipelineDynamicStateCreateFlags              flags
  static_cast<uint32_t>(dynamic_states.size()),                 // uint32_t                                       dynamicStateCount&dynamic_states[0]                                            // const VkDynamicState                          *pDynamicStates
};

7.Tutorial04.cpp, function CreatePipeline()

It is done by using a structure of type VkPipelineDynamicStateCreateInfo, which contains the following fields:

  • sType – Parameter defining the type of a given structure, here equal to VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO.
  • pNext – Parameter reserved for extensions.
  • flags – Parameter reserved for future use.
  • dynamicStateCount – Number of elements in pDynamicStates array.
  • pDynamicStates – Array containing enums, specifying which parts of a pipeline should be marked as dynamic. Each element of this array is of type VkDynamicState.

Pipeline Object Creation

We now have defined all the necessary parameters of a graphics pipeline, so we can create a pipeline object. Here is the code that does it:

VkGraphicsPipelineCreateInfo pipeline_create_info = {
  VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,              // VkStructureType                                sType
  nullptr,                                                      // const void                                    *pNext
  0,                                                            // VkPipelineCreateFlags                          flags
  static_cast<uint32_t>(shader_stage_create_infos.size()),      // uint32_t                                       stageCount&shader_stage_create_infos[0],                                // const VkPipelineShaderStageCreateInfo         *pStages&vertex_input_state_create_info,                              // const VkPipelineVertexInputStateCreateInfo    *pVertexInputState;&input_assembly_state_create_info,                            // const VkPipelineInputAssemblyStateCreateInfo  *pInputAssemblyState
  nullptr,                                                      // const VkPipelineTessellationStateCreateInfo   *pTessellationState&viewport_state_create_info,                                  // const VkPipelineViewportStateCreateInfo       *pViewportState&rasterization_state_create_info,                             // const VkPipelineRasterizationStateCreateInfo  *pRasterizationState&multisample_state_create_info,                               // const VkPipelineMultisampleStateCreateInfo    *pMultisampleState
  nullptr,                                                      // const VkPipelineDepthStencilStateCreateInfo   *pDepthStencilState&color_blend_state_create_info,                               // const VkPipelineColorBlendStateCreateInfo     *pColorBlendState&dynamic_state_create_info,                                   // const VkPipelineDynamicStateCreateInfo        *pDynamicState
  pipeline_layout.Get(),                                        // VkPipelineLayout                               layout
  Vulkan.RenderPass,                                            // VkRenderPass                                   renderPass
  0,                                                            // uint32_t                                       subpass
  VK_NULL_HANDLE,                                               // VkPipeline                                     basePipelineHandle
  -1                                                            // int32_t                                        basePipelineIndex
};

if( vkCreateGraphicsPipelines( GetDevice(), VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &Vulkan.GraphicsPipeline ) != VK_SUCCESS ) {
  std::cout << "Could not create graphics pipeline!"<< std::endl;
  return false;
}
return true;

8.Tutorial04.cpp, function CreatePipeline()

The most important variable, which contains references to all pipeline parameters, is of type VkGraphicsPipelineCreateInfo. The only change from the previous tutorial is an addition of the pDynamicState parameter, which points to a structure of VkPipelineDynamicStateCreateInfo type, described above. Every pipeline state, which is specified as dynamic, must be set through a proper function call during command buffer recording.

The pipeline object itself is created by calling the vkCreateGraphicsPipelines() function.

Vertex Buffer Creation

To use vertex attributes, apart from specifying them during pipeline creation, we need to prepare a buffer that will contain all the data for these attributes. From this buffer, the values for attributes will be read and provided to the vertex shader.

In Vulkan, buffer and image creation consists of at least two stages. First, we create the object itself. Next, we need to create a memory object, which will then be bound to the buffer (or image). From this memory object, the buffer will take its storage space. This approach allows us to specify additional parameters for the memory and control it with more details.

To create a (general) buffer object we call vkCreateBuffer(). It accepts, among other parameters, a pointer to a variable of type VkBufferCreateInfo, which defines parameters of created buffer. Here is the code responsible for creating a buffer used as a source of data for vertex attributes:

VertexData vertex_data[] = {
  {
    -0.7f, -0.7f, 0.0f, 1.0f,
    1.0f, 0.0f, 0.0f, 0.0f
  },
  {
    -0.7f, 0.7f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 0.0f
  },
  {
    0.7f, -0.7f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 0.0f
  },
  {
    0.7f, 0.7f, 0.0f, 1.0f,
    0.3f, 0.3f, 0.3f, 0.0f
  }
};

Vulkan.VertexBuffer.Size = sizeof(vertex_data);

VkBufferCreateInfo buffer_create_info = {
  VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,             // VkStructureType        sType
  nullptr,                                          // const void            *pNext
  0,                                                // VkBufferCreateFlags    flags
  Vulkan.VertexBuffer.Size,                         // VkDeviceSize           size
  VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                // VkBufferUsageFlags     usage
  VK_SHARING_MODE_EXCLUSIVE,                        // VkSharingMode          sharingMode
  0,                                                // uint32_t               queueFamilyIndexCount
  nullptr                                           // const uint32_t        *pQueueFamilyIndices
};

if( vkCreateBuffer( GetDevice(), &buffer_create_info, nullptr, &Vulkan.VertexBuffer.Handle ) != VK_SUCCESS ) {
  std::cout << "Could not create a vertex buffer!"<< std::endl;
  return false;
}

9.Tutorial04.cpp, function CreateVertexBuffer()

At the beginning of the CreateVertexBuffer() function we define a set of values for position and color attributes. First, four position components are defined for first vertex, next four color components for the same vertex, after that four components of a position attribute for second vertex are specified, next a color values for the same vertex, after that position and color for third and fourth vertices. The size of this array is used to define the size of a buffer. Remember though that internally graphics driver may require more storage for a buffer than the size requested by an application.

Next we define a variable of VkBufferCreateInfo type. It is a structure with the following fields:

  • sType – Type of the structure, which should be set to VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO value.
  • pNext – Parameter reserved for extensions.
  • flags – Parameter defining additional creation parameters. Right now it allows creation of a buffer backed by a sparse memory (something similar to a mega texture). As we don’t want to use sparse memory, we can set this parameter to zero.
  • size – Size, in bytes, of a buffer.
  • usage – This parameter defines how we intend to use this buffer in future. We can specify that we want to use buffer as a uniform buffer, index buffer, source of data for transfer (copy) operations, and so on. Here we intend to use this buffer as a vertex buffer. Remember that we can’t use a buffer for a purpose that is not defined during buffer creation.
  • sharingMode – Sharing mode, similarly to swapchain images, defines whether a given buffer can be accessed by multiple queues at the same time (concurrent sharing mode) or by just a single queue (exclusive sharing mode). If a concurrent sharing mode is specified, we must provide indices of all queues that will have access to a buffer. If we want to define an exclusive sharing mode, we can still reference this buffer in different queues, but only in one at a time. If we want to use a buffer in a different queue (submit commands that reference this buffer to another queue), we need to specify buffer memory barrier that transitions buffer’s ownership from one queue to another.
  • queueFamilyIndexCount – Number of queue indices in pQueueFamilyIndices array (only when concurrent sharing mode is specified).
  • pQueueFamilyIndices – Array with indices of all queues that will reference buffer (only when concurrent sharing mode is specified).

To create a buffer we must call vkCreateBuffer() function.

Buffer Memory Allocation

We next create a memory object that will back the buffer’s storage.

VkMemoryRequirements buffer_memory_requirements;
vkGetBufferMemoryRequirements( GetDevice(), buffer, &buffer_memory_requirements );

VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties( GetPhysicalDevice(), &memory_properties );

for( uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i ) {
  if( (buffer_memory_requirements.memoryTypeBits & (1 << i)) &&
    (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ) {

    VkMemoryAllocateInfo memory_allocate_info = {
      VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,     // VkStructureType                        sType
      nullptr,                                    // const void                            *pNext
      buffer_memory_requirements.size,            // VkDeviceSize                           allocationSize
      i                                           // uint32_t                               memoryTypeIndex
    };

    if( vkAllocateMemory( GetDevice(), &memory_allocate_info, nullptr, memory ) == VK_SUCCESS ) {
      return true;
    }
  }
}
return false;

10.Tutorial04.cpp, function AllocateBufferMemory()

First we must check what the memory requirements for a created buffer are. We do this by calling the vkGetBufferMemoryRequirements() function. It stores parameters for memory creation in a variable that we provided the address of in the last parameter. This variable must be of type VkMemoryRequirements and it contains information about required size, memory alignment, and supported memory types. What are memory types?

Each device may have and expose different memory types—heaps of various sizes that have different properties. One memory type may be a device’s local memory located on the GDDR chips (thus very, very fast). Another may be a shared memory that is visible both for a graphics card and a CPU. Both the graphics card and application may have access to this memory, but such memory type is slower than the device local-only memory (which is accessible only to a graphics card).

To check what memory heaps and types are available, we need to call the vkGetPhysicalDeviceMemoryProperties() function, which stores information about memory in a variable of type VkPhysicalDeviceMemoryProperties. It contains the following information:

  • memoryHeapCount – Number of memory heaps exposed by a given device.
  • memoryHeaps – An array of memory heaps. Each heap represents a memory of different size and properties.
  • memoryTypeCount – Number of different memory types exposed by a given device.
  • memoryTypes – An array of memory types. Each element describes specific memory properties and contains an index of a heap that has these particular properties.

Before we can allocate a memory for a given buffer, we need to check which memory type fulfills a buffer’s memory requirements. If we have additional, specific needs, we can also check them. For all of this, we iterate over all available memory types. Buffer memory requirements have a field called memoryTypeBits and if a bit on a given index is set in this field, it means that for a given buffer we can allocate a memory of the type represented by that index. But we must remember that while there must always be a memory type that fulfills buffer’s memory requirements, it may not support some other, specific needs. In this case we need to look for another memory type or change our additional requirements.

Here, our additional requirement is that memory needs to be host visible. This means that application can map this memory and get access to it—read it or write data to it. Such memory is usually slower than the device local-only memory, but this way we can easily upload data for our vertex attributes. The next tutorial will show how to use device local-only memory for better performance.

Fortunately, the host visible requirement is popular, and it should be easy to find a memory type that supports both the buffer’s memory requirements and the host visible property. We then prepare a variable of type VkMemoryAllocateInfo and fill all its fields:

  • sType – Type of the structure, here set to VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO.
  • pNext – Pointer reserved for extensions.
  • allocationSize – Minimum required memory size that should be allocated.
  • memoryTypeIndex – Index of a memory type we want to use for a created memory object. It is the index of one of bits that are set (has value of one) in buffer’s memory requirement.

After we fill such a structure we call vkAllocateMemory() and check whether the memory object allocation succeeded.

Binding a Buffer’s Memory

When we are done creating a memory object, we must bind it to our buffer. Without it, there will be no storage space in a buffer and we won’t be able to store any data in it.

if( !AllocateBufferMemory( Vulkan.VertexBuffer.Handle, &Vulkan.VertexBuffer.Memory ) ) {
  std::cout << "Could not allocate memory for a vertex buffer!"<< std::endl;
  return false;
}

if( vkBindBufferMemory( GetDevice(), Vulkan.VertexBuffer.Handle, Vulkan.VertexBuffer.Memory, 0 ) != VK_SUCCESS ) {
  std::cout << "Could not bind memory for a vertex buffer!"<< std::endl;
  return false;
}

11.Tutorial04.cpp, function CreateVertexBuffer()

AllocateBufferMemory() is a function that allocates a memory object. It was presented earlier. When a memory object is created, we bind it to the buffer by calling the vkBindBufferMemory() function. During the call we must specify a handle to a buffer, handle to a memory object, and an offset. Offset is very important and requires some additional explanation.

When we queried for buffer memory requirement, we acquired information about required size, memory type, and alignment. Different buffer usages may require different memory alignment. The beginning of a memory object (offset of 0) satisfies all alignments. This means that all memory objects are created at addresses that fulfill the requirements of all different usages. So when we specify a zero offset, we don’t have to worry about anything.

But we can create larger memory object and use it as a storage space for multiple buffers (or images). This, in fact, is the recommended behavior. Creating larger memory objects means we are creating fewer memory objects. This allows driver to track fewer objects in general. Memory objects must be tracked by a driver because of OS requirements and security measures. Larger memory objects don’t cause big problems with memory fragmentation. Finally, we should allocate larger memory amounts and keep similar objects in them to increase cache hits and thus improve performance of our application.

But when we allocate larger memory objects and bind them to multiple buffers (or images), not all of them can be bound at offset zero. Only one can be bound at this offset, others must be bound further away, after a space used by the first buffer (or image). So the offset for the second, and all other buffers bound to the same memory object, must meet alignment requirements reported by the query. And we must remember it. That’s why alignment member is important.

When our buffer is created and memory for it is allocated and bound, we can fill the buffer with data for vertex attributes.

Uploading Vertex Data

We have created a buffer and we have bound a memory that is host visible. This means we can map this memory, acquire a pointer to this memory, and use this pointer to copy data from our application to the buffer itself (similar to the OpenGL’s glBufferData() function):

void *vertex_buffer_memory_pointer;
if( vkMapMemory( GetDevice(), Vulkan.VertexBuffer.Memory, 0, Vulkan.VertexBuffer.Size, 0, &vertex_buffer_memory_pointer ) != VK_SUCCESS ) {
  std::cout << "Could not map memory and upload data to a vertex buffer!"<< std::endl;
  return false;
}

memcpy( vertex_buffer_memory_pointer, vertex_data, Vulkan.VertexBuffer.Size );

VkMappedMemoryRange flush_range = {
  VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,            // VkStructureType        sType
  nullptr,                                          // const void            *pNext
  Vulkan.VertexBuffer.Memory,                       // VkDeviceMemory         memory
  0,                                                // VkDeviceSize           offset
  VK_WHOLE_SIZE                                     // VkDeviceSize           size
};
vkFlushMappedMemoryRanges( GetDevice(), 1, &flush_range );

vkUnmapMemory( GetDevice(), Vulkan.VertexBuffer.Memory );

return true;

12.Tutorial04.cpp, function CreateVertexBuffer()

To map memory, we call the vkMapMemory() function. In the call we must specify which memory object we want to map and a region to access. Region is defined by an offset from the beginning of a memory object’s storage and size. After the successful call we acquire a pointer. We can use it to copy data from our application to the provided memory address. Here we copy vertex data from an array with vertex positions and colors.

After a memory copy operation and before we unmap a memory (we don’t need to unmap it, we can keep a pointer and this shouldn’t impact performance), we need to tell the driver which parts of the memory was modified by our operations. This operation is called flushing. Through it we specify all memory ranges that our application copied data to. Ranges don’t have to be continuous. Ranges are defined by an array of VkMappedMemoryRange elements which contain these fields:

  • sType – Structure type, here equal to VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE.
  • pNext – Pointer reserved for extensions.
  • memory – Handle of a mapped and modified memory object.
  • offset – Offset (from the beginning of a given memory object’s storage) at which a given range starts.
  • size – Size, in bytes, of an affected region. If the whole memory, from an offset to the end, was modified, we can use the special value of VK_WHOLE_SIZE.

When we define all memory ranges that should be flashed, we can call the vkFlushMappedMemoryRanges() function. After that, the driver will know which parts were modified and will reload them (that is, refresh cache). Reloading usually occurs on barriers. After modifying a buffer, we should set a buffer memory barrier, which will tell the driver that some operations influenced a buffer and it should be refreshed. But, fortunately, in this case such a barrier is placed implicitly by the driver on a submission of a command buffer that references the given buffer and no additional operations are required. Now we can use this buffer during rendering commands recording.

Rendering Resources Creation

We now must prepare resources required for a command buffer recording. In previous tutorials we have recorded one static command buffer for each swapchain image. Here we will reorganize the rendering code. We will still display a simple, static scene, but the approach presented here is useful in real-life scenarios, where displayed scenes are dynamic.

To record command buffers and submit them to queue in an efficient way, we need four types of resources: command buffers, semaphores, fences and framebuffers. Semaphores, as we already discussed, are used for internal queue synchronization. Fences, on the other hand, allow the application to check if some specific situation occurred, e.g. if command buffer’s execution after it was submitted to queue, has finished. If necessary, application can wait on a fence, until it is signaled. In general, semaphores are used to synchronize queues (GPU) and fences are used to synchronize application (CPU).

To render a single frame of animation we need (at least) one command buffer, two semaphores—one for a swapchain image acquisition (image available semaphore) and the other to signal that presentation may occur (rendering a finished semaphore)—a fence, and a framebuffer. The fence is used later to check whether we can rerecord a given command buffer. We will keep several numbers of such rendering resources, which we can call a virtual frame. The number of these virtual frames (consisting of a command buffer, two semaphores, a fence, and a framebuffer) should be independent of a number of swapchain images.

The rendering algorithm progresses like this: We record rendering commands to the first virtual frame and then submit it to a queue. Next we record another frame (command buffer) and submit it to queue. We do this until we are out of all virtual frames. At this point we will start reusing frames by taking the oldest (least recently submitted) command buffer and rerecording it again. Then we will use another command buffer, and so on.

This is where the fences come in. We are not allowed to record a command buffer that has been submitted to a queue until its execution in the queue is finished. During command buffer recording, we can use the “simultaneous use” flag, which allows us to record or resubmit a command buffer that has already been submitted. This may impact performance though. A better way is to use fences and check whether a command buffer is not used any more. If a graphics card is still processing a command buffer, we can wait on a fence associated with a given command buffer, or use this additional time for other purposes, like improved AI calculations, and after some time check again to see whether a fence is signaled.

How many virtual frames should we have? One is not enough. When we record and submit a single command buffer, we immediately wait until we can rerecord it. It is a waste of time of both the CPU and the GPU. The GPU is usually faster, so waiting on a CPU causes more waiting on a GPU. We should keep the GPU as busy as possible. That is why thin APIs like Vulkan were created. Using two virtual frames gives huge performance gain, as there is much less waiting both on the CPU and the GPU. Adding a third virtual frame gives additional performance gain, but the increase isn’t as big. Using four or more groups of rendering resource doesn’t make sense, as the performance gain is negligible (of course this may depend on the complexity of the rendered scene and calculations performed by the CPU-like physics or AI). When we increase the number of virtual frames we also increase the input lag, as we present a frame that’s one to three frames behind the CPU. So two or three virtual frames seems to be the most reasonable compromise between performance, memory usage, and input lag.

You may wonder why the number of virtual frames shouldn’t be connected with the number of swapchain images. This approach may influence the behavior of our application. When we create a swapchain, we ask for the minimal required number of images, but the driver is allowed to create more. So different hardware vendors may implement drivers that offer different numbers of swapchain images, even for the same requirements (present mode and minimal number of images). When we connect the number of virtual frames with a number of swapchain images, our application will use only two virtual frames on one graphics card, but four virtual frames on another graphics card. This may influence both performance and mentioned input lag. It’s not a desired behavior. By keeping the number of virtual frames fixed, we can control our rendering algorithm and fine-tune it to our needs, that is, balance the time spent on rendering and AI or physics calculations.

Command Pool Creation

Before we can allocate a command buffer, we first need to create a command pool.

VkCommandPoolCreateInfo cmd_pool_create_info = {
  VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,       // VkStructureType                sType
  nullptr,                                          // const void                    *pNext
  VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | // VkCommandPoolCreateFlags       flags
  VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
  queue_family_index                                // uint32_t                       queueFamilyIndex
};

if( vkCreateCommandPool( GetDevice(), &cmd_pool_create_info, nullptr, pool ) != VK_SUCCESS ) {
  return false;
}
return true;

13.Tutorial04.cpp, function CreateCommandPool()

The command pool is created by calling vkCreateCommandPool(), which requires us to provide a pointer to a variable of type VkCommandPoolCreateInfo. The code remains mostly unchanged, compared to previous tutorials. But this time, two additional flags are added for command pool creation:

  • VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT – Indicates that command buffers, allocated from this pool, may be reset individually. Normally, without this flag, we can’t rerecord the same command buffer multiple times. It must be reset first. And, what’s more, command buffers created from one pool may be reset only all at once. Specifying this flag allows us to reset command buffers individually, and (even better) it is done implicitly by calling the vkBeginCommandBuffer() function.
  • VK_COMMAND_POOL_CREATE_TRANSIENT_BIT – This flag tells the driver that command buffers allocated from this pool will be living for a short amount of time, they will be often recorded and reset (re-recorded). This information helps optimize command buffer allocation and perform it more optimally.

Command Buffer Allocation

Allocating command buffers remains the same as previously.

for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
  if( !AllocateCommandBuffers( Vulkan.CommandPool, 1, &Vulkan.RenderingResources[i].CommandBuffer ) ) {
    std::cout << "Could not allocate command buffer!"<< std::endl;
    return false;
  }
}
return true;

14.Tutorial04.cpp, function CreateCommandBuffers()

The only change is that command buffers are gathered into a vector of rendering resources. Each rendering resource structure contains a command buffer, image available semaphore, rendering finished semaphore, a fence and a framebuffer. Command buffers are allocated in a loop. The number of elements in a rendering resources vector is chosen arbitrarily. For this tutorial it is equal to three.

Semaphore Creation

The code responsible for creating a semaphore is simple and the same as previously shown:

VkSemaphoreCreateInfo semaphore_create_info = {
  VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,      // VkStructureType          sType
  nullptr,                                      // const void*              pNext
  0                                             // VkSemaphoreCreateFlags   flags
};

for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
  if( (vkCreateSemaphore( GetDevice(), &semaphore_create_info, nullptr, &Vulkan.RenderingResources[i].ImageAvailableSemaphore ) != VK_SUCCESS) ||
    (vkCreateSemaphore( GetDevice(), &semaphore_create_info, nullptr, &Vulkan.RenderingResources[i].FinishedRenderingSemaphore ) != VK_SUCCESS) ) {
    std::cout << "Could not create semaphores!"<< std::endl;
    return false;
  }
}
return true;

15.Tutorial04.cpp, function CreateSemaphores()

Fence Creation

Here is the code responsible for creating fence objects:

VkFenceCreateInfo fence_create_info = {
  VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,              // VkStructureType                sType
  nullptr,                                          // const void                    *pNext
  VK_FENCE_CREATE_SIGNALED_BIT                      // VkFenceCreateFlags             flags
};

for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
  if( vkCreateFence( GetDevice(), &fence_create_info, nullptr, &Vulkan.RenderingResources[i].Fence ) != VK_SUCCESS ) {
    std::cout << "Could not create a fence!"<< std::endl;
    return false;
  }
}
return true;

16.Tutorial04.cpp, function CreateFences()

To create a fence object we call the vkCreateFence() function. It accepts, among other parameters, a pointer to a variable of type VkFenceCreateInfo, which has the following members:

  • sType – Type of the structure. Here it should be set to VK_STRUCTURE_TYPE_FENCE_CREATE_INFO.
  • pNext – Pointer reserved for extensions.
  • flags – Right now this parameter allows for creating a fence that is already signaled.

A fence may have two states: signaled and unsignaled. The application checks whether a given fence is in a signaled state, or it may wait on a fence until the fence gets signaled. Signaling is done by the GPU after all operations submitted to the queue are processed. When we submit command buffers, we can provide a fence that will be signaled when a queue has finished executing all commands that were issued in this one submit operation. After the fence is signaled, it is the application’s responsibility to reset it to an unsignaled state.

Why create a fence that is already signaled? Our rendering algorithm will record commands to the first command buffer, then to the second command buffer, after that to the third, and then once again to the first (after its execution in a queue has ended). We use fences to check whether we can record a given command buffer once again. But what about the first recording? We don’t want to keep separate code paths for the first command buffer recording and for the following recording operations. So when we issue a command buffer recording for the first time, we also check whether a fence is already signaled. But because we didn’t submit a given command buffer, the fence associated with it can’t become signaled as a result of the finished execution. So the fence needs to be created in an already signaled state. This way, for the first time, we won’t have to wait for it to become signaled (as it is already signaled), but after the check we will reset it and immediately go to the recording code. After that we submit a command buffer and provide the same fence, which will get signaled by the queue when operations are done. The next time, when we want to rerecord rendering commands to the same command buffer, we can do the same operations: wait on the fence, reset it, and then start command buffer recording.

Drawing

Now we are nearly ready to record rendering operations. We are recording each command buffer just before it is submitted to the queue. We record one command buffer and submit it, then the next command buffer and submit it, then yet another one. After that we take the first command buffer, check whether we can use it, and we record it and submit it to the queue.

static size_t           resource_index = 0;
RenderingResourcesData ¤t_rendering_resource = Vulkan.RenderingResources[resource_index];
VkSwapchainKHR          swap_chain = GetSwapChain().Handle;
uint32_t                image_index;

resource_index = (resource_index + 1) % VulkanTutorial04Parameters::ResourcesCount;

if( vkWaitForFences( GetDevice(), 1, ¤t_rendering_resource.Fence, VK_FALSE, 1000000000 ) != VK_SUCCESS ) {
  std::cout << "Waiting for fence takes too long!"<< std::endl;
  return false;
}
vkResetFences( GetDevice(), 1, ¤t_rendering_resource.Fence );

VkResult result = vkAcquireNextImageKHR( GetDevice(), swap_chain, UINT64_MAX, current_rendering_resource.ImageAvailableSemaphore, VK_NULL_HANDLE, &image_index );
switch( result ) {
  case VK_SUCCESS:
  case VK_SUBOPTIMAL_KHR:
    break;
  case VK_ERROR_OUT_OF_DATE_KHR:
    return OnWindowSizeChanged();
  default:
    std::cout << "Problem occurred during swap chain image acquisition!"<< std::endl;
    return false;
}

if( !PrepareFrame( current_rendering_resource.CommandBuffer, GetSwapChain().Images[image_index], current_rendering_resource.Framebuffer ) ) {
  return false;
}

VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submit_info = {
  VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // VkStructureType              sType
  nullptr,                                                // const void                  *pNext
  1,                                                      // uint32_t                     waitSemaphoreCount
  ¤t_rendering_resource.ImageAvailableSemaphore,    // const VkSemaphore           *pWaitSemaphores
  &wait_dst_stage_mask,                                   // const VkPipelineStageFlags  *pWaitDstStageMask;
  1,                                                      // uint32_t                     commandBufferCount¤t_rendering_resource.CommandBuffer,              // const VkCommandBuffer       *pCommandBuffers
  1,                                                      // uint32_t                     signalSemaphoreCount
  ¤t_rendering_resource.FinishedRenderingSemaphore  // const VkSemaphore           *pSignalSemaphores
};

if( vkQueueSubmit( GetGraphicsQueue().Handle, 1, &submit_info, current_rendering_resource.Fence ) != VK_SUCCESS ) {
  return false;
}

VkPresentInfoKHR present_info = {
  VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,                     // VkStructureType              sType
  nullptr,                                                // const void                  *pNext
  1,                                                      // uint32_t                     waitSemaphoreCount
  ¤t_rendering_resource.FinishedRenderingSemaphore, // const VkSemaphore           *pWaitSemaphores
  1,                                                      // uint32_t                     swapchainCount
  &swap_chain,                                            // const VkSwapchainKHR        *pSwapchains&image_index,                                           // const uint32_t              *pImageIndices
  nullptr                                                 // VkResult                    *pResults
};
result = vkQueuePresentKHR( GetPresentQueue().Handle, &present_info );

switch( result ) {
  case VK_SUCCESS:
    break;
  case VK_ERROR_OUT_OF_DATE_KHR:
  case VK_SUBOPTIMAL_KHR:
    return OnWindowSizeChanged();
  default:
    std::cout << "Problem occurred during image presentation!"<< std::endl;
    return false;
}

return true;

17.Tutorial04.cpp, function Draw()

So first we take the least recently used rendering resource. Then we wait until the fence associated with this group is signaled. If it is, this means that we can safely take a command buffer and record it. But this also means that we can take semaphores used to acquire and present an image that was referenced in a given command buffer. We shouldn’t use the same semaphore for different purposes or in two different submit operations, until the previous submission is finished. The fences prevent us from altering both command buffers and semaphores. And as you will soon see, framebuffers too.

When a fence is finished, we reset the fence and perform normal drawing-related operations: we acquire an image, record operations rendering into an acquired image, submit the command buffer, and present an image.

After that we take another set of rendering resources and perform these same operations. Thanks to keeping three groups of rendering resources, three virtual frames, we lower the time wasted on waiting for a fence to be signaled.

Recording a Command Buffer

A function responsible for recording a command buffer is quite long. This time it is even longer, because we use a vertex buffer and a dynamic viewport and scissor test. And we also create temporary framebuffers!

Framebuffer creation is simple and fast. Keeping framebuffer objects along with a swapchain means that we need to recreate them when the swapchain needs to be recreated. If our rendering algorithm is complicated, we have multiple images and framebuffers associated with them. If those images need to have the same size as swapchain images, we need to recreate all of them (to include potential size change). So it is better and more convenient to create framebuffers on demand. This way, they always have the desired size. Framebuffers operate on image views, which are created for a given, specific image. When a swapchain is recreated, old images are invalid, not existent. So we must recreate image views and also framebuffers.

In the “03 – First Triangle” tutorial, we had framebuffers of a fixed size and they had to be recreated along with a swapchain. Now we have a framebuffer object in each of our virtual frame group of resources. Before we record a command buffer, we create a framebuffer for an image to which we will be rendering, and of the same size as that image. This way, when swapchain is recreated, the size of the next frame will be immediately adjusted and a handle of the new swapchain’s image and its image view will be used to create a framebuffer.

When we record a command buffer that uses a render pass and framebuffer objects, the framebuffer must remain valid for the whole time the command buffer is processed by the queue. When we create a new framebuffer, we can’t destroy it until commands submitted to a queue are finished. But as we are using fences, and we have already waited on a fence associated with a given command buffer, we are sure that the framebuffer can be safely destroyed. We then create a new framebuffer to include potential size and image handle changes.

if( framebuffer != VK_NULL_HANDLE ) {
  vkDestroyFramebuffer( GetDevice(), framebuffer, nullptr );
}

VkFramebufferCreateInfo framebuffer_create_info = {
  VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                sType
  nullptr,                                        // const void                    *pNext
  0,                                              // VkFramebufferCreateFlags       flags
  Vulkan.RenderPass,                              // VkRenderPass                   renderPass
  1,                                              // uint32_t                       attachmentCount
  &image_view,                                    // const VkImageView             *pAttachments
  GetSwapChain().Extent.width,                    // uint32_t                       width
  GetSwapChain().Extent.height,                   // uint32_t                       height
  1                                               // uint32_t                       layers
};

if( vkCreateFramebuffer( GetDevice(), &framebuffer_create_info, nullptr, &framebuffer ) != VK_SUCCESS ) {
  std::cout << "Could not create a framebuffer!"<< std::endl;
  return false;
}

return true;

18.Tutorial04.cpp, function CreateFramebuffer()

When we create a framebuffer, we take current swapchain extents and image view for an acquired swapchain image.

Next we start recording a command buffer:

if( !CreateFramebuffer( framebuffer, image_parameters.View ) ) {
  return false;
}

VkCommandBufferBeginInfo command_buffer_begin_info = {
  VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,        // VkStructureType                        sType
  nullptr,                                            // const void                            *pNext
  VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,        // VkCommandBufferUsageFlags              flags
  nullptr                                             // const VkCommandBufferInheritanceInfo  *pInheritanceInfo
};

vkBeginCommandBuffer( command_buffer, &command_buffer_begin_info );

VkImageSubresourceRange image_subresource_range = {
  VK_IMAGE_ASPECT_COLOR_BIT,                          // VkImageAspectFlags                     aspectMask
  0,                                                  // uint32_t                               baseMipLevel
  1,                                                  // uint32_t                               levelCount
  0,                                                  // uint32_t                               baseArrayLayer
  1                                                   // uint32_t                               layerCount
};

if( GetPresentQueue().Handle != GetGraphicsQueue().Handle ) {
  VkImageMemoryBarrier barrier_from_present_to_draw = {
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,           // VkStructureType                        sType
    nullptr,                                          // const void                            *pNext
    VK_ACCESS_MEMORY_READ_BIT,                        // VkAccessFlags                          srcAccessMask
    VK_ACCESS_MEMORY_READ_BIT,                        // VkAccessFlags                          dstAccessMask
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,                  // VkImageLayout                          oldLayout
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,                  // VkImageLayout                          newLayout
    GetPresentQueue().FamilyIndex,                    // uint32_t                               srcQueueFamilyIndex
    GetGraphicsQueue().FamilyIndex,                   // uint32_t                               dstQueueFamilyIndex
    image_parameters.Handle,                          // VkImage                                image
    image_subresource_range                           // VkImageSubresourceRange                subresourceRange
  };
  vkCmdPipelineBarrier( command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier_from_present_to_draw );
}

VkClearValue clear_value = {
  { 1.0f, 0.8f, 0.4f, 0.0f },                         // VkClearColorValue                      color
};

VkRenderPassBeginInfo render_pass_begin_info = {
  VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,           // VkStructureType                        sType
  nullptr,                                            // const void                            *pNext
  Vulkan.RenderPass,                                  // VkRenderPass                           renderPass
  framebuffer,                                        // VkFramebuffer                          framebuffer
  {                                                   // VkRect2D                               renderArea
    {                                                 // VkOffset2D                             offset
      0,                                                // int32_t                                x
      0                                                 // int32_t                                y
    },
    GetSwapChain().Extent,                            // VkExtent2D                             extent;
  },
  1,                                                  // uint32_t                               clearValueCount
  &clear_value                                        // const VkClearValue                    *pClearValues
};

vkCmdBeginRenderPass( command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE );

19.Tutorial04.cpp, function PrepareFrame()

First we define a variable of type VkCommandBufferBeginInfo and specify that a command buffer will be submitted only once. When we specify a VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT flag, we can’t submit a given command buffer more times. After each submission it must be reset. But the recording operation resets it due to the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag used during command pool creation.

Next we define subresource ranges for image memory barriers. The layout transitions of the swapchain images are performed implicitly inside a render pass, but if the graphics and presentation queue are different, the queue transition must be manually performed.

After that we begin a render pass with the temporary framebuffer object.

vkCmdBindPipeline( command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, Vulkan.GraphicsPipeline );

VkViewport viewport = {
  0.0f,                                               // float                                  x
  0.0f,                                               // float                                  y
  static_cast<float>(GetSwapChain().Extent.width),    // float                                  width
  static_cast<float>(GetSwapChain().Extent.height),   // float                                  height
  0.0f,                                               // float                                  minDepth
  1.0f                                                // float                                  maxDepth
};

VkRect2D scissor = {
  {                                                   // VkOffset2D                             offset
    0,                                                  // int32_t                                x
    0                                                   // int32_t                                y
  },
  {                                                   // VkExtent2D                             extent
    GetSwapChain().Extent.width,                        // uint32_t                               width
    GetSwapChain().Extent.height                        // uint32_t                               height
  }
};

vkCmdSetViewport( command_buffer, 0, 1, &viewport );
vkCmdSetScissor( command_buffer, 0, 1, &scissor );

VkDeviceSize offset = 0;
vkCmdBindVertexBuffers( command_buffer, 0, 1, &Vulkan.VertexBuffer.Handle, &offset );

vkCmdDraw( command_buffer, 4, 1, 0, 0 );

vkCmdEndRenderPass( command_buffer );

if( GetGraphicsQueue().Handle != GetPresentQueue().Handle ) {
  VkImageMemoryBarrier barrier_from_draw_to_present = {
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,           // VkStructureType                        sType
    nullptr,                                          // const void                            *pNext
    VK_ACCESS_MEMORY_READ_BIT,                        // VkAccessFlags                          srcAccessMask
    VK_ACCESS_MEMORY_READ_BIT,                        // VkAccessFlags                          dstAccessMask
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,                  // VkImageLayout                          oldLayout
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,                  // VkImageLayout                          newLayout
    GetGraphicsQueue().FamilyIndex,                   // uint32_t                               srcQueueFamilyIndex
    GetPresentQueue().FamilyIndex,                    // uint32_t                               dstQueueFamilyIndex
    image_parameters.Handle,                          // VkImage                                image
    image_subresource_range                           // VkImageSubresourceRange                subresourceRange
  };
  vkCmdPipelineBarrier( command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier_from_draw_to_present );
}

if( vkEndCommandBuffer( command_buffer ) != VK_SUCCESS ) {
  std::cout << "Could not record command buffer!"<< std::endl;
  return false;
}
return true;

20.Tutorial04.cpp, function PrepareFrame()

Next we bind a graphics pipeline. It has two states marked as dynamic: viewport and scissor test. So we prepare structures that define viewport and scissor test parameters. The dynamic viewport state is set by calling the vkCmdSetViewport() function. The dynamic scissor test is set by calling the vkCmdSetScissor() function. This way, our graphics pipeline can be used for rendering into images of different sizes.

One last thing before we can draw anything is to bind appropriate vertex buffer, providing buffer data for vertex attributes. We do this through the vkCmdBindVertexBuffers() function call. We specify a binding number (which set of vertex attributes should take data from this buffer), a pointer to a buffer handle (or more handles if we want to bind buffers for multiple bindings) and an offset. The offset specifies that data for vertex attributes should be taken from further parts of the buffer. But we can’t specify offset larger than the size of a corresponding buffer (buffer, not memory object bound to this buffer).

Now we have specified all the required elements: framebuffer, viewport and scissor test, and a vertex buffer. We can draw the geometry, finish the render pass, and end the command buffer.

Tutorial04 Execution

Here is the result of rendering operations:

We are rendering a quad that has different colors in each corner. Try resizing the window; previously, the triangle was always the same size, only the black frame on the right and bottom sides of an application window grew larger or smaller. Now, thanks to the dynamic viewport state, the quad is growing or shrinking along with the window.

Cleaning Up

After rendering and before closing the application, we should destroy all resources. Here is a code responsible for this operation:

if( GetDevice() != VK_NULL_HANDLE ) {
  vkDeviceWaitIdle( GetDevice() );

  for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
    if( Vulkan.RenderingResources[i].Framebuffer != VK_NULL_HANDLE ) {
      vkDestroyFramebuffer( GetDevice(), Vulkan.RenderingResources[i].Framebuffer, nullptr );
    }
    if( Vulkan.RenderingResources[i].CommandBuffer != VK_NULL_HANDLE ) {
      vkFreeCommandBuffers( GetDevice(), Vulkan.CommandPool, 1, &Vulkan.RenderingResources[i].CommandBuffer );
    }
    if( Vulkan.RenderingResources[i].ImageAvailableSemaphore != VK_NULL_HANDLE ) {
      vkDestroySemaphore( GetDevice(), Vulkan.RenderingResources[i].ImageAvailableSemaphore, nullptr );
    }
    if( Vulkan.RenderingResources[i].FinishedRenderingSemaphore != VK_NULL_HANDLE ) {
      vkDestroySemaphore( GetDevice(), Vulkan.RenderingResources[i].FinishedRenderingSemaphore, nullptr );
    }
    if( Vulkan.RenderingResources[i].Fence != VK_NULL_HANDLE ) {
      vkDestroyFence( GetDevice(), Vulkan.RenderingResources[i].Fence, nullptr );
    }
  }

  if( Vulkan.CommandPool != VK_NULL_HANDLE ) {
    vkDestroyCommandPool( GetDevice(), Vulkan.CommandPool, nullptr );
    Vulkan.CommandPool = VK_NULL_HANDLE;
  }

  if( Vulkan.VertexBuffer.Handle != VK_NULL_HANDLE ) {
    vkDestroyBuffer( GetDevice(), Vulkan.VertexBuffer.Handle, nullptr );
    Vulkan.VertexBuffer.Handle = VK_NULL_HANDLE;
  }

  if( Vulkan.VertexBuffer.Memory != VK_NULL_HANDLE ) {
    vkFreeMemory( GetDevice(), Vulkan.VertexBuffer.Memory, nullptr );
    Vulkan.VertexBuffer.Memory = VK_NULL_HANDLE;
  }

  if( Vulkan.GraphicsPipeline != VK_NULL_HANDLE ) {
    vkDestroyPipeline( GetDevice(), Vulkan.GraphicsPipeline, nullptr );
    Vulkan.GraphicsPipeline = VK_NULL_HANDLE;
  }

  if( Vulkan.RenderPass != VK_NULL_HANDLE ) {
    vkDestroyRenderPass( GetDevice(), Vulkan.RenderPass, nullptr );
    Vulkan.RenderPass = VK_NULL_HANDLE;
  }
}

21.Tutorial04.cpp, destructor

We destroy all resources after the device completes processing all commands submitted to all its queues. We destroy resources in a reverse order. First we destroy all rendering resources: framebuffers, command buffers, semaphores and fences. Fences are destroyed by calling the vkDestroyFence() function. Then the command pool is destroyed. After that we destroy buffer by calling the vkDestroyBuffer() function, and free memory object by calling the vkFreeMemory() function. Finally the pipeline object and a render pass are destroyed.

Conclusion

This tutorial is based on the”03 – First Triangle” tutorial. We improved rendering by using vertex attributes in a graphics pipeline and vertex buffers bound during command buffer recording. We described the number and layout of vertex attributes. We introduced dynamic pipeline states for the viewport and scissors test. We learned how to create buffers and memory objects and how to bind one to another. We also mapped memory and upload data from the CPU to the GPU.

We have created a set of rendering resources that allow us to efficiently record and issue rendering commands. These resources consisted of command buffers, semaphores, fences, and framebuffers. We learned how to use fences, how to set up values of dynamic pipeline states, and how to bind vertex buffers (source of vertex attribute data) during command buffer recording.

The next tutorial will present staging resources. These are intermediate buffers used to copy data between the CPU and GPU. This way, buffers (or images) used for rendering don’t have to be mapped by an application and can be bound to a device’s local (very fast) memory.


Go to: API without Secrets: Introduction to Vulkan* Part 5: Staging Resources (To Be Continued...)


Notices

No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document.

Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.

This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice. Contact your Intel representative to obtain the latest forecast, schedule, specifications and roadmaps.

The products and services described may contain defects or errors known as errata which may cause deviations from published specifications. Current characterized errata are available on request.

Copies of documents which have an order number and are referenced in this document may be obtained by calling 1-800- 548-4725 or by visiting www.intel.com/design/literature.htm.

This sample source code is released under the Intel Sample Source Code License Agreement.

Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.

*Other names and brands may be claimed as the property of others.

© 2016 Intel Corporation.

Crowdfunding Home Security - The Story of Orbii (So Far)

$
0
0

When Orbii Co-Founder Omar Barlas was shopping for a camera to set up in his home two years ago, he didn’t know it would lead to a brand-new business venture. But when he wasn’t able to find what he was looking for—a single device that was drivable from room to room—he decided to make it himself, a decision which, so far, has led to a showcase at 2016’s Consumer Electronics Show and an Indiegogo campaign that was fully-funded within the first week.

We sat down with him to discuss Orbii’s success, as well as what they learned through the process, including what they would or wouldn’t do next time around.

Orbii’s Story

In the simple time-honored tradition of invention, Orbii came to be because there was a need unfulfilled—Barlas wanted a single camera for home security purposes that he could drive from room to room, but all of the available options required multiple camera setups for full coverage. Barlas moved quickly into prototyping, intent upon creating a working model as soon as possible—something that could not only prove the concept and define future iterations, but something that could also give reviewers and potential customers a chance to experience the idea firsthand.

The first prototype was showcased at CES 2016, and received great response. This confirmed Orbii’s initial market research findings, and it also gave them the opportunity to talk to more potential consumers. Additional market research was done through Orbii’s website, where potential consumers were able to sign-up and offer their insights. One key learning was that there was an active secondary market of pet owners who were interested in the product as a way to monitor their pets when they weren’t at home—using Orbii’s microphone and speaker to interact with them from afar. While this didn’t change the overall focus of the product, it allowed the product developers to keep all of their customers in mind when considering new features, and encouraged them to think about additional creative opportunities in marketing.

Further prototyping and market validation led the way to the launch of the Indiegogo campaign in May 2016. In order to fund the development of the product, Orbii needed pre-sales. In order to encourage pre-sales, they offered a variety of incentives for potential buyers—essentially providing deep discounts to customers who were willing to order early and support product development.

As a result of their success on Indiegogo, the company will continue to develop the product, while also continuing to explore distribution and partnership opportunities. The first round of products is expected to launch in April 2017.

Understanding Their Audience

Orbii’s primary audience is Homeowners and Business Owners, but they are also serving a number of secondary markets, including:

  • Parents
  • Children of Elderly Parents
  • Pet Owners
  • Real Estate Inspectors
  • Building Contractors
  • Aged Care Services
  • First Responders
  • Military

This audience was defined through early market research and a survey. Orbii’s primary method of research was in simple face-to-face communications: They talked to people. At a variety of small tech events, at CES, at New York Tech Day 2016, they demonstrated the prototype and asked people what they thought about it, how they might use it—what promise it provided them.

This phase of market research also gave them an opportunity to pivot. The core functionality, features, and market remained the same, but based on early feedback they made some changes to the internal design of the product.
 

Crowdfunding: How and Why?

Orbii chose crowdfunding for two reasons—to fund mainstream product development, and to conduct market research. Because this method involves presenting your idea and selling your future product to actual consumers, it gives you access to additional market research, and a group of dedicated consumers who are willing to support you both in terms of finances and in terms of product feedback and requests.
 

Crowdfunding? How Does it Work?

Dedicated manager. First things first—consider hiring a full-time person to manage your crowdfunding campaign. It’s not enough to just put something up and see what happens, and chances are good that the core team will need to continue working on product development at the same time. This person will need to prepare weekly updates, and to respond to consumer questions in a timely manner, while allowing for ongoing simultaneous development. Responding to consumers is really key, both in terms of engaging with that consumer, and for the benefit of future potential customers. “If you don’t respond, then you’ll stop getting backers coming back to your site. That’s what people see,” said Barlas.

Creation of assets. Consumers need to see the product in action, and the best way to do that is through professional videos and lifestyle photos of the product in action. Orbii hired an outside marketing firm to do this work for them, knowing that their talents were better left focused on product and business development, while they left the marketing to the pros. It’s also a good idea to provide videos of product testing and use cases—these may be less polished than the other assets, but they help legitimize your claims, and they also involve consumers in the process, providing them with a sense of ownership as well as excitement bout the final product to come.

Incentives. Consumers need a reason to pre-order, especially when a company is new and untested. There are a variety of ways to approach this, but the key thing is to give them something beyond what they’d be able to buy in a store. Orbii deeply discounted the product for early backers, allowing them to not only get the product first, but to get it for a significantly-reduced price.

Results! Orbii’s crowdfunding campaign was highly successful. After meeting 100% of their initial goal of $6,000 by the end of the first week, they went on to raise a total of $35,000 in the first month, from more than 260 backers. There are hurdles to crowdfunding while development is still in process, but in this case it paid off, allowing Orbii to continue to fund development, and letting customers get in on the ground floor.
 

What Would Orbii Have Done Differently?

Despite Orbii’s success, there are always things to learn and things that could be approached differently the next time around. Barlas told us there were three key things that in retrospect they should have done more aggressively before launching the campaign:

1.Collection of sign-ups from interested customers early on.
During all of those great conversations at tech events, while they were conducting market research and demonstrating the prototype, they could have done more to collect sign-ups from interested consumers. With more effort, a really great contact list could’ve been created.

2.Collection of more social media/facebook followers early on.
Similarly, more efforts could’ve been made online to capture and collect sign-ups from those who’d expressed an interest in the product.

3.Align press/media contacts to write about Orbii on the day of launch.
Timing is key. Orbii had a lot of good press at CES in January, but the campaign didn’t launch until May. Because of this, they weren’t able to maximize their exposure. If they’d coordinated their efforts and had interested reviewers and tech press lined up to write about the product in May, they would have had a larger audience for their Indiegogo campaign, and even more success.
 

Marketing

What did Orbii do to get the word out? For a crowdfunding campaign to be a success, it’s important to share your story and your product idea with as many people as possible. Orbii’s primary approach, as we’ve discussed, was to attend tech events and talk to people one-on-one. This gave them a venue to demonstrate the prototypes, but it was also a natural way to let people know about the upcoming campaign. Additionally, Orbii hired an agency to help conduct a Facebook campaign, which brought in new product backers. 
 

Pricing

Orbii needed to not only determine pricing for its product, they also needed to figure out pricing for incentives. “Whenever you’re thinking about crowdfunding, you’ve got to offer some special deal to the backers, otherwise no one would be interested in ordering in advance,” says Barlas. In Orbii’s case, they went with a price discount model. The campaign kicked off with pricing at 60% off of the retail price. The next week, they offered 50% off, then 40% off the following week. This allowed interested customers to buy in early, and to save in the process. Increasing the price each week, and publicizing those upcoming price increases helped drive excitement and encourage people to buy while the price was still low.

Pricing for the product itself was a more straightforward task. They looked at the market to see how other products were priced, and based on their extensive prototyping and pre-orders, they determined the estimated cost of the Bill of Materials, and the retail price was calculated from that BOM.  
 

Keys to Success

1.Be consistent and aggressive with product development.
Despite hurdles, continue working toward the product that you’ve envisioned, building prototypes and revising along the way. Even when Orbii’s team had to use personal funds and other revenue streams to fund development, they kept going.

2.Build an MVP quickly.
You need a functional prototype that performs the way it is supposed to perform, so move quickly to this stage of development, and create your MVP, or Minimum Viable Product. Consumers will know if it’s real or not, and press will need to evaluate the prototype in order to write about it.

3.Hire good marketers.
Know where your talents lie and hire help for the things outside your expertise (when you can). Orbii’s team is made of developers and visionaries, so they looked outside for marketing, and were able to remain focused on product and business development.  
 

Future Plans

Now that Orbii has been funded, what happens next? Orbii's team remains focused on production and the consumer product launch next year. At the same time, they’re working to build relationships with distributors, and looking for potential partners, such as a Cloud Services Provider. They are also continuing to raise investment for faster production, building on the success of their crowdfunding campaign.


Exploring 1:N transcoding pipelines with Intel® Media Server Studio

$
0
0

Contents

 Introduction

As the device ecosystem becomes increasingly more diverse, the need to tailor media content to the consumer becomes even more prevalent. Media content providers must adapt to the changing needs of their customers by adapting their offerings to whatever device characteristics their users prefer. Video transcoding has become the norm for those distributing video, where a single source is transformed into multiple copies with different resolutions and bitrates designed to preform optimally on a particular device.

Intel® Media Server Studio is a development library that exposes the media acceleration capabilities of Intel® platforms for decoding, encoding and video processing, it provides an ideal toolset that enables media providers to adapt to the needs of their customers. This whitepaper details the architectural and design decisions that are necessary when using Intel Media Server Studio to develop a 1:N transcoding pipeline - whereas one input stream would be transcoded to multiple (N) outputs to target the different end-user device profiles.

Conceptually, a 1:N transcoding pipeline can be considered as follows:

N transcoding pipeline

An efficient implementation of a media transcoding infrastructure consists of multiple 1:N pipelines being run in parallel, thus maximizing the amount of streams that can be processed at any one time and reducing the total cost of ownership of the platform. Intel Media Server Studio can make use of the specialized media hardware built into the servers based on the Intel® Xeon processor E3 to accelerate the pipelines using the GPU resources and achieve a higher density than CPU only based designs.

Before creating an optimized system of 1:N pipelines from scratch, you may benefit from an in-depth look at the samples provided by the Intel Media Server Studio package. In particular, the sample_multi_transcode sample can be used to simulate a 1:N pipeline by specifying the inputs/outputs in the parameter file, such as:

	 (File: OneToN.Par)

	-i::h264 <input.H264> -o::sink -join -hw
	-i::source -w 1280 -h 720 -o::h264 <output1.h264> -join  -hw
	-i::source -w 864  -h 480 -o::h264 <output2.h264> -join  -hw
	-i::source -w 640  -h 360 -o::h264 <output3.h264> -join  -hw
	-i::source -w 432  -h 240 -o::h264 <output4.h264> -join  -hw

		   Command:
			./sample_multi_transcode  -par OneToN.Par

The above parameter file specifies a simple 1:N transcode scenario. The first line of the parameter file invokes Intel Media Server Studio's H264 decoder by specifying the input file <input.h264>. The decoder will output the uncompressed frames to an output named "sink", which is a special command line parameter that redirects the frames to an internal buffer instead of writing the file to disk. The second through fifth lines of the parameter file invoke Intel Media Server Studio's h264 encoder to transform the frames into the target resolutions. Instead of reading from disk, the encoder reads from the "source" - which is the same buffer that the decoder writes the uncompressed frames into. The encoded content's resolution and output filename is also specified.

Notice the efficiency of the solution - only a single decoder and multiple encoders are instantiated. A frame is decoded only once and then submitted to each of the encoders. The "-join" and "-hw" command line flags further optimize the solution. The "-join” instructs the program to combine the scheduling and memory management of all components that are active, and the "-hw" instructs the program to execute the pipeline on the GPU rather than the CPU.

Sample_multi_transcode is an ideal program to gauge the expected performance of a 1:N pipeline. It is however a quite sophisticated piece of code that can be used to simulate a variety of different workloads. This complexity can make it difficult for the Intel Media Server Studio novice to extrapolate the key architectural components needed to develop a similar solution in house. The following summarizes how sample_multi_transcode implements this style of pipeline; use it in conjunction with careful code analysis when implementing an in-house solution.

 Distributing the work

Using the same workload from above we can see that there are five separate work items specified. One decoder and four separate encoders. The first work item decodes the source file to a raw frame, and the remaining items consume the raw frame, and process, and encode it to various bit streams. All the work items are relatively autonomous to one another; however they are all dependent upon the decoder output. Each of these tasks is a natural candidate for parallelization and should be run in its own thread for maximum efficiency.

The Sample_multi_transcode source code enables the separation of work item tasks by using a general purpose class called CTranscodingPipeline. This class contains all the methods and structures necessary to create an autonomous work item that can be instantiated in its own thread. This class sometimes causes confusion with new developers trying to understand how the sample works because of the large size of methods and structures. CTranscodingPipeline is designed to support any type of workload and thus has many methods and member variables that are only used if relevant to the task at hand. For example, one instance of CTranscodingPipeline may use a decoder and file reader, whereas another instance may have a VPP and encoder component and no decoder. This is exactly what happens when the above parameter file is used to run a 1:N pipeline. The inclusion of the VPP component is used to scale the decoded video frame to the correct resolution prior to encoding, so it makes sense to include both the VPP and encoder components into the same instance for CTranscodingPipeline.

CTranscodingPipeline

 Initialization

 Pipelines and Sessions

Developers familiar with the Intel® Media SDK API know the concept of a MFXVideoSession. A MFXVideoSession is created to hold the context of an Intel Media SDK pipeline. The reference manual states that each MFXVideoSession can contain a single instance of a decoder, VPP, and encoder component. In the case above, each CTranscodingPipeline creates its own MFXVideoSession for the active components of its instance. The process of creating and joining the sessions together occurs in the CTranscodingPipeline.Init() function.

 Memory

The efficient sharing of data between the different components of the 1:N pipeline is paramount to utilizing the hardware resources in an effective way. Intel Media Server Studio performs best when the media pipelines are configured to run in an asynchronous fashion. By default, Intel Media Server Studio delegate’s memory management to the application and it’s the applications responsibility to allocate sufficient memory.

Application developers have a choice about how to implement the 1:N memory allocation scheme. The first option is to use an external allocator. The application implements the functions for alloc (), free (), lock (), and unlock () using either system or video memory. Determining what type of memory to allocate is left to the application to decide, but generally when an application needs to process frames during the transcode (apply special filters for instance), the application provided allocator is a good choice. The alternative choice is use to allow Intel Media Server Studio to do the work of choosing the most optimal memory type dependent on the run time circumstances. This surface neutral type - or opaque - memory is used when Sample_multi_transcode is configured with a 1:N workload:

  m_mfxDecParams.IOPattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
  m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;

Using opaque memory makes sense in the 1:N transcode workload where the focus is on simply converting a single video source into multiple copies. The frames flow through the pipeline from one component to another unimpeded by any interaction from the application. If the application does need to operate on the fame data mid-pipeline it needs to explicitly synchronize, which is a performance penalty. In those cases, an external allocator would be preferred.

When sample_multi_transcode configures a 1:N pipeline it does not use an external allocator, but rather an opaque memory scheme to defer the responsibility of frame memory back to the underlying API. When opaque memory is used, the SDK will choose the memory type (system or GPU) at run time to maximize efficiency. This choice occurs during CTranscodingPipeline.Init().

Letting the API select the best memory for the type of job not only gives the application more resiliency to adapt to runtime environments, but it is also easier to maintain.

Regardless of whether opaque or application allocated memory is used the API still needs frame allocation headers to be setup prior to the initialization of the pipeline. The allocation of frame headers sometimes confuses new users of the Intel Media Server Studio. When using opaque memory, the application is only released from the responsibility of allocating the actual frame memory and assigning it to the Data.MemId field of the mfxFrameSurface1 structure. The application still needs to allocate sufficient surface headers for the decoder and encoder to work with. VPP functions will share the encoder’s surfaces since the two components are tightly integrated into a single pipeline. There are many examples throughout the Intel Media Server Studio’s documentation that explain how to allocate the surface headers. The end result will be two surface arrays – one for the decoder, the other for the encoder with the Data.MemId set to 0 for opaque memory or set to a valid surface returned by the applications allocator.

The use of the opaque memory type does however require an extra initialization step connecting the surface pools together and informing the API how the frames should flow through the pipelines. The code for this can be found in the InitOpaqueAllocBuffers()function.

Decode:

	m_DecOpaqueAlloc.Out.Surfaces = &m_pSurfaceDecPool[0];
    m_DecOpaqueAlloc.Out.NumSurface = (mfxU16)m_pSurfaceDecPool.size();
    m_DecOpaqueAlloc.Out.Type = (mfxU16)(MFX_MEMTYPE_BASE(m_DecSurfaceType) |
								MFX_MEMTYPE_FROM_DECODE);

Vpp:

	m_VppOpaqueAlloc.In = m_DecOpaqueAlloc.Out;
	m_VppOpaqueAlloc.Out =m_EncOpaqueAlloc.In;

Encode:

	m_EncOpaqueAlloc.In.Surfaces = &m_pSurfaceEncPool[0];
    m_EncOpaqueAlloc.In.NumSurface = (mfxU16)m_pSurfaceEncPool.size();
	m_EncOpaqueAlloc.In.Type = (mfxU16)(MFX_MEMTYPE_BASE(m_EncSurfaceType) |
								MFX_MEMTYPE_FROM_ENCODE);

The connections between the opaque memory structures inform the API how the frames flow through the pipeline, which can be expressed graphically using the OpaqueAlloc functions as follows:

OpaqueAlloc functions

 Runtime Operation of the 1:N Pipeline

 Communicating between the Sessions

Sample_multi_transcode's 1:N pipeline configuration consists of an (N) amount of CTranscodingPipeline instances containing a specific operation (decode, VPP, encode, and so on.). Each of these instances carries its own MFXVideoSession. The passing of frame data across the threads is handled by a set of mutex protected buffers called the SafetySurfaceBuffer.

class SafetySurfaceBuffer
    {
    public:
        struct SurfaceDescriptor
        {
            ExtendedSurface   ExtSurface;
            mfxU32            Locked;
        };

        SafetySurfaceBuffer(SafetySurfaceBuffer *pNext);
        virtual ~SafetySurfaceBuffer();

        void              AddSurface(ExtendedSurface Surf);
        mfxStatus         GetSurface(ExtendedSurface &Surf);
        mfxStatus         ReleaseSurface(mfxFrameSurface1* pSurf);

        SafetySurfaceBuffer               *m_pNext;

    protected:

        MSDKMutex                 m_mutex;
        std::list<SurfaceDescriptor>       m_SList;
    private:
        DISALLOW_COPY_AND_ASSIGN(SafetySurfaceBuffer);
    };

The SafetySurfaceBuffer is the key to understanding how the frames flow from the decoder to the encoders across the threads. During initialization of sample_multi_transcode, the program will calculate the number of instances of CTranscodingPipeline it needs to implement the 1:N pipeline. For each instance of a "source" pipeline, a SafetySurfaceBuffer is created in the function CreateSafetyBuffers(). The buffers are created and linked together as such:

SafetySurfaceBuffer created in the function CreateSafetyBuffers()

There is no SafetySurfaceBuffer created for the sink (decoder) pipeline, just those instances of CTranscodingPipeline that contain VPP and encoders. When the pipeline that contains the decoder completes the frame, the working surface and sync point are placed in the ExtendedSurface structure and added to SafetySurfaceBuffer. The application does not need to explicitly sync the frame, but rather copies the pointer into the ExtendedSurface.

CTranscodingPipeline that contain VPP and encoders

 Starting the Pipelines

Once the process of creating and configuring the different instances of CTranscodingPipeline and SafetySurfaceBuffer have been completed, they can be dispatched into separate threads for execution. This process occurs in the Launcher::Run() function.

MSDKThread * pthread = NULL;
    for (i = 0; i < totalSessions; i++)
    {
        pthread = new MSDKThread(sts, ThranscodeRoutine, (void *)m_pSessionArray[i]);
        m_HDLArray.push_back(pthread);
    }
    for (i = 0; i < m_pSessionArray.size(); i++)
    {
        m_HDLArray[i]->Wait();
    }

Each instance of the m_pSessionArray contains a preconfigured pipeline which is dispatched into its own thread.  The callback “ThranscodeRoutine” is where the main execution starts.

mfxU32 MFX_STDCALL TranscodingSample::ThranscodeRoutine(void   *pObj)
{
    mfxU64 start = TranscodingSample::GetTick();
    ThreadTranscodeContext *pContext = (ThreadTranscodeContext*)pObj;
    pContext->transcodingSts = MFX_ERR_NONE;
    for(;;)
    {
        while (MFX_ERR_NONE == pContext->transcodingSts)
        {
            pContext->transcodingSts = pContext->pPipeline->Run();
        }
        if (MFX_ERR_MORE_DATA == pContext->transcodingSts)
        {
            // get next coded data
            mfxStatus bs_sts = pContext->pBSProcessor->PrepareBitstream();
            // we can continue transcoding if input bistream presents
            if (MFX_ERR_NONE == bs_sts)
            {
                MSDK_IGNORE_MFX_STS(pContext->transcodingSts, MFX_ERR_MORE_DATA);
                continue;
            }
            // no need more data, need to get last transcoded frames
            else if (MFX_ERR_MORE_DATA == bs_sts)
            {
                pContext->transcodingSts = pContext->pPipeline->FlushLastFrames();
            }
        }

        break; // exit loop
    }

    MSDK_IGNORE_MFX_STS(pContext->transcodingSts, MFX_WRN_VALUE_NOT_CHANGED);

    pContext->working_time = TranscodingSample::GetTime(start);
    pContext->numTransFrames = pContext->pPipeline->GetProcessFrames();

    return 0;
}

Each instance of CTranscodingPipeline will be started and continue processing until it runs out of data at which point the final frames are flushed out of the pipelines and the transcoder terminates.

 Performance Characteristics on 1:N

The Intel Media Server Studio is a highly configurable solution that gives the developer a large array of controls to use in order to tune their pipelines to meet most requirements. As in all video transcoder products, a tradeoff must be made between throughput and video quality. By leaving the quality parameters to their defaults we can investigate some of the pure performance flags of sample_multi_transcode, which impact the overall throughput of the solution.

These experiments were performed on the Intel® Core™ i7-5557U processor with Iris™ Pro graphics 6100 using CentOS* 7.1. We used sample_multi_transcode from the Intel Media Server Studio 2015 R6.

Two key settings to investigate first are “Join” and “Async Depth”.

The "-join" command maps to the Intel Media SDK API’s MFXJoinSession function. When sessions are joined, the first session will become the parent and handle the scheduling of resources for all other sessions joined to it. This feature allows for the efficient reuse of resources between the active sessions.

The “-async_depth” command controls the depth of the asynchronous queue that Intel Media Server Studio maintains. A deeper queue allows more tasks to be implemented in parallel before the application must explicitly “sync” to free the resources. A large async depth could cause a shortage of the resources that are available. The following par files are used to show the impact of Join and Non-Joined sessions at various Async depths:

-i::h264  ~/Content/h264/brazil_25full.264 -o::sink –hw –async 1 -join
-i::source -w 1280 -h 720 -o::h264 /dev/null -hw -async 1 -join
-i::source -w 864  -h 480 -o::h264 /dev/null -hw -async 1 -join
-i::source -w 640  -h 360 -o::h264 /dev/null -hw -async 1 -join
-i::source -w 432  -h 240 -o::h264 /dev/null h264 -hw -async 1 -join

Note: -async was varied between 1 and 10 with both –join and without –join.   The output was directed to /dec/null to eliminate the disk I/O from being calculated into the total Frames per second (FPS).

N Joined vs Non-Joined Session Performance

This workload deliberately focused on lower resolution encoding as it is a more difficult case; higher-resolution outputs typically have better performance characteristics.  As you can see from the above graph, the “-join” flag does not have a significant impact on the throughput of this workload.  A small async depth does improve the average FPS of the pipelines, but at larger values it does not contribute to the overall performance.  We recommended that you gauge the level of performance of your own workloads with both join and non-join configurations.

Now we can vary the quality settings to see what impact it has on the throughput of the 1:N pipeline. We use this par file to vary the quality settings:

-i::h264  ~/Content/h264/brazil_25full.264 -o::sink –hw –async 2 –u 1
-i::source -w 1280 -h 720 -o::h264 /dev/null -hw -async 2 –u 1
-i::source -w 864  -h 480 -o::h264 /dev/null -hw -async 2 –u 1
-i::source -w 640  -h 360 -o::h264 /dev/null -hw -async 2 –u 1
-i::source -w 432  -h 240 -o::h264 /dev/null –hw –async 2 –u 1

Note: -u (TU) was varied between 1 and 7 without –Join and Async Depth held constant at 2. The output was directed to /dec/null to eliminate the disk I/O from being calculated into the total FPS.

As the graph above shows, the Target Usage parameter has a large impact on the overall throughput of the 1:N pipeline. We encourage you to experiment with the target usage settings to determine your ideal throughput vs the resulting quality to find the ideal settings.

There are a large amount of other settings the Intel Media Server Studio provides that can be further adjusted to find the best performance for your individual workloads. The multitude of different encoding options such as BRC, buffer sizes, and low latency options can be used to find the right balance between speed and quality. Sample_multi_transcode exposes most of these options though the command line.

 Conclusion

This paper discussed the key architectural and performance characteristics of using Intel Media Server Studio’s sample_multi_transcode when configured in a simple 1:N pipeline. This type of workload is ideal for transcoding single-source content into multiple resolution outputs. This and many other samples are available to developers here: https://software.intel.com/en-us/intel-media-server-studio-support/code-samples. Media content providers who want to target an ever-increasing device ecosystem can utilize sample_multi_transcode when designing their own content delivery systems.

Compiling for the Intel® Xeon Phi™ processor and the Intel® AVX-512 ISA

$
0
0

Introduction

This document briefly gives an overview of the Intel® Advanced Vector Extensions 512 (Intel® AVX-512) and shows different ways to build an application for the Intel® Xeon Phi™ processor x200 using the Intel® compiler.

Intel® AVX-512 Family of Instructions

Intel AVX-512 instructions deliver a comprehensive set of functionality and higher performance than Intel® AVX and Intel® AVX2 family of instructions (see section 1.2 here for a complete description). Intel AVX-512 instruction set architecture (ISA) consists of the following groups:

  • Intel AVX-512 Foundation instructions (AVX-512F) are the base of Intel AVX-512. They include extensions of the Intel AVX and Intel AVX2 family of SIMD instructions but are encoded using EVEX encoding scheme with support for 512-bit vector registers, up to 32 vector registers in 64-bit mode, and conditional processing using opmask registers.

  • Intel AVX-512 Conflict Detection instructions (AVX-512CD) provide efficient conflict detection to allow more loops to be vectorized.

  • Intel AVX-512 Exponential and Reciprocal instructions (AVX-512ER) are designed to provide building blocks for accelerating certain transcendental math computations.

  • Intel AVX-512 Prefetch instructions (AVX-512PF) are new instructions that can be useful for reducing memory operation latency exposure that involve gather/scatter instructions.

  • Intel (AVX-512BW) extend AVX-512 instruction set to cover 8-bit and 16-bit integer operations.

  • Intel (AVX-512DQ) are new 32-bit and 64-bit AVX-512 instructions for enhancing integer and floating-point operations.

  • Intel AVX-512 Vector Length Extensions (AVX-512VL) extends most AVX-512 operations to also operate on XMM (128-bit) and YMM (256-bit) registers, instead of only ZMM (512-bit) registers.

AVX-512F, AVX-512CD, AVX-512ER, and AVX-512PF are implemented in the Intel Xeon Phi processor x200 (code named Knights Landing) while AVX-512F, AVX-512CD, AVX-512BW, AVX-512DQ, and AVX-512VL are implemented in the Intel® Xeon® processor.

Compiling for the Intel® Xeon Phi™ processor x200

The instruction groups common to both the Intel Xeon Phi processor x200 and the Intel Xeon processor are AVX-512F and AVX-512CD. The AVX-512ER and AVX-512PF groups are implemented in the Intel Xeon Phi processor x200 only. The AVX-512BW, AVX-512DQ and AVX-512VL groups are implemented only in the Intel Xeon processor.

You can use the following Intel compiler options to build an executable for Intel AVX-512 code generation:

  • The compiler option –xcode

    The general form is –xcode on Linux* and /Qxcode on Windows* where code is the argument. This option tells the compiler which processor features it may target. To generate Intel AVX-512 instructions, you can use one of the three different arguments to generate different categories:

    -xCOMMON-AVX512: use this option to generate AVX-512F and AVX-512CD.

    -xMIC-AVX512: use this option to generate AVX-512F, AVX-512CD, AVX-512ER and AVX-512FP.

    -xCORE-AVX512: use this option to generate AVX-512F, AVX-512CD, AVX-512BW, AVX-512DQ and AVX-512VL.

    For example, to generate Intel AVX-512 instructions for the Intel Xeon Phi processor x200, you should use the option –xMIC-AVX512. For example, on a Linux system

    $ icc –xMIC-AVX512 application.c

    This compiler option is useful when you want to build a huge binary for the Intel Xeon Phi processor x200. Instead of building it on the coprocessor where it will take more time, build it on an Intel Xeon processor-based machine

  • The compiler option –axcode

    The general form is –axcode on Linux and /Qaxcode on Windows where code is the argument. This option is used for multiple, feature-specific, auto-dispatch code paths for Intel® processors and generates a baseline-code path (generic IA code path). The baseline-code path will be used when the hardware platform does not support the specific ISA. You can use one of the three different arguments to generate different Intel AVX-512 categories:

    -axCOMMON-AVX512: use this option to generate AVX-512F and AVX-512CD; a baseline-code path is also generated.

    -axMIC-AVX512: use this option to generate AVX-512F, AVX-512CD, AVX-512ER and AVX-512FP; a baseline-code path is also generated.

    -axCORE-AVX512: use this option to generate AVX-512F, AVX-512CD, AVX-512BW, AVX-512DQ and AVX-512VL; a baseline-code path is also generated.

    This compiler option is useful when you try to build a binary that can run on multiple platforms.

  • The compiler option –xHost

    The general form is -xHost on Linux and /QxHost on Windows. This option is used for the highest instruction set available on the compilation host processor.

    For example, on an Intel® Xeon® v3 system running Linux use the following command to generate AVX2 ISA

    $ icc –xHost application.c

    However, if running the same command on the Intel Xeon Phi processor x200, it will generate Intel AVX-512 for that architecture (equivalent to –xMIC-AVX512)

    If running the same command on future Intel Xeon processors that support Intel AVX-512, it will generate Intel AVX-512 for that architecture (equivalent to -xCORE-AVX512).

Note that all options above are not available for the Intel® Xeon Phi™ x100 coprocessor.

Using the Intel® Software Development Emulator to test your executable

As a note, you can also use the Intel® Software Development Emulator (Intel® SDE) to test your executable for the Intel Xeon Phi processor x200. Intel SDE is a software emulator and is mainly used for code emulating future instructions only, not for performance. This article here provides information in details on how to run the Intel SDE for the Intel Xeon Phi processor x200.  

Conclusion

This document briefly summarized different Intel AVX-512 groups and what options in the Intel compiler you can use to build an executable for the Intel Xeon Phi processor x200 to properly take advantage of Intel AVX-512 ISA.

References

What Is the Intel® Edison Module?

$
0
0

The Intel® Edison Module is a tiny SD card–sized computing chip designed for building Internet of Things (IoT) and wearable computing products. The Edison module contains a high-speed, dual-core processing unit, integrated Wi-Fi*, Bluetooth* low energy, storage and memory, and a broad spectrum of input/output (I/O) options for interfacing with user systems. Because of its small footprint and low power consumption, the Edison module is an ideal choice for projects that need a lot of processing power without being connected to a power supply.

The Edison module is meant to be embedded in devices or development boards for connectivity and power options. To get started, Intel® provides the Intel® Edison Kit for Arduino* and Intel® Edison Breakout Board Kit*, which you can use for rapid prototyping. For production deployment, you can also create a custom board.

The Intel® Edison Kit for Arduino allows for quick and easy prototyping with open source hardware and the widely used Arduino software development environment. The kit gives you the option to extend the Edison module to interface with existing Arduino UNO R3 shields for extended functionality. The Intel® Edison Breakout Board Kit primarily provides power and USB connectivity options; for instance, you can connect the Edison board to your laptop’s USB port and get started quickly.

Intel® Edison Module Overview

Figure 1 shows the block diagram of the Edison module.

Figure 1. Block diagram of the Intel® Edison Module

 

[Source: http://download.intel.com/support/edison/sb/edisonmodule_hg_331189004.pdf]

The module consists of an Intel® Atom™ processor operating at a clock speed of 500 MHz and 4 GB of managed flash memory. By default, the Yocto Linux* operating system is installed in flash memory.

For Wi-Fi and Bluetooth low energy connectivity, the module includes a Broadcom BCM43340 chip that supports standard dual-band 2.4-GHz and 5-GHz IEEE 802.11 a/b/g/n standards as well as Wi-Fi Protected Access (WPA) and WPA2 (personal) for powerful encryption and authentication. This connectivity option makes it easier to connect Edison module embedded devices to existing Wi-Fi infrastructure in a standardized way. Bluetooth low energy enables Edison devices to connect to other Bluetooth low energy devices like smartphones so that the smartphone can act as a gateway to connect to the Internet.
Connectivity options for an IoT product is a key design consideration for how the IoT product would interface with the world. With the Edison module providing support for the two most widely-used connectivity options, it’s easier to focus on the actual product. The Edison module interfaces with user systems through a Hirose 70-pin DF40 Series header connector, which has 40 pins dedicated to general-purpose I/O (GPIO).

The Edison module provides a solid set of unique capabilities, starting with a small form factor, high-speed dual core processor, low power usage, standard connectivity options, and a broad set of I/O support. These features enable a variety of use cases for building innovative connected solutions.

Programming the Intel® Edison Module

To program the Edison module, you can use the C, C++, Python*, or JavaScript* (Node.js*) programming language. To develop and debug the device code on Edison development boards or devices, download the integrated development environment (IDE) for your programming environment. For instance, you can download Intel® XDK for JavaScript, Intel® System Studio IoT Edition for C/C++, Intel® System Studio IoT Edition for Java, or the Arduino IDE for programming an Edison board with Arduino. The choice of IDE depends on your project and device requirements as well as which programming language you’ll use to interface with the devices.

To interact with sensors and actuators on Edison devices (or any supported device), Intel® provides the Libmraa* library. Libmraa provides an abstraction layer on top of supported hardware, so that you can read data from sensors and actuators in a standard way and create portable code that works across supported platforms. To check supported sensors and actuators from various manufacturers for Edison devices, browse the Useful Packages & Modules (UPM) Sensor/Actuator repository at GitHub* (https://github.com/intel-iot-devkit/upm). UPM is a high-level repository for various sensors, and provides a standard pattern for integrating with sensors using the Libmraa library. With the option of widely-used programming languages and a community of various sensor projects, you can reuse your existing programming knowledge to develop connected products, and use the Libmraa library to interact easily with GPIO pins for I/O functionality.

Connecting Edison Devices to a Cloud Platform

Based on your IoT solution, you’ll have to connect Edison devices to a cloud platform for further computation and advanced analytics of sensor data. Edison devices provide seamless support for connecting to leading cloud platforms like Microsoft Azure*, IBM Watson* IoT Platform, or Amazon Web Services* (AWS*).

These cloud platforms typically provide a software development kit (SDK) or device SDK in C++, Python, or JavaScript, which makes it easier to connect Edison devices (or any device, for that matter). The typical development process involves reading the sensor values from the devices and transmitting the sensor data to the cloud platform over supported protocols like Message Queuing Telemetry Transport or Advanced Message Queuing Protocol from the SDK library. See the following links for details on connecting Edison devices to cloud platforms:

To start building IoT applications quickly, you could also buy starter kits that include an Edison board and come preinstalled with connectivity to a cloud platform. For details, check out the following links:

What Will You Develop?

The Edison module provides endless opportunities for building connected products for consumer and industrial use cases:

  • Consumer Use Cases. Use cases range from embedding an Edison module in wearable devices like watches or health devices for tracking various health and lifestyle parameters to home automation devices for controlling entertainment equipment or smart energy utilization.
  • Edge Analytics. The Edison module, because of its dual-core, high-speed processor and low power usage, can be embedded in industrial devices to provide local analytics and computation support. Example use cases include running analytics or algorithms locally on devices for condition-based maintenance of machinery equipment and raising alerts to image analysis and object recognition for surveillance and security purposes in smart buildings.

For other projects that makers are developing with this tiny, innovative module, check out:

Summary

This article looked at the Intel® Edison Module, its hardware specification, and itscore set of features—all of which provide unique opportunities for makers to build connected products. It looked at the programming languages that the Edison module supports, the available IDEs, and the Libmraa library for rapid development and deployment of Edison devices. Finally, you saw how to connect Edison devices to cloud platforms and discovered use cases for Edison technology. The Edison module provides many capabilities; it’s up to you and your imagination to discover what you can build.

Intel® Quark™ SE with Intel® System Studio for Microcontrollers. Programming Guide for Quark SE with a GPIO sample.

$
0
0

Intel® Quark™ SE with Intel® System Studio for Microcontrollers
GPIO: Programming Guide

 

 

 

 

Overview

The purpose of this lab is to provide an introduction to the programming of the Intel® Quark SE (Atlas Hills) using Intel® System Studio 2016 for Microcontrollers Update 1 ( ISSM ). The project used in this lab is a GPIO sample. This sample demonstrates using Quark SE GPIO and Pin Interrupt capabilities. When a rising edge signal comes in to the pin with interrupt, it triggers ISR which sends a message through the UART.

Prerequisites

  • Host machine:
    • PC running Microsoft Windows 7 or later with an available USB ports.
  • Software:
    • Intel® System Studio for Microcontrollers 2016 Update 1.
  • Hardware:
    • Intel® Quark™ SE board (Atlas Hills).
    • 2 USB Type A to Micro USB Type B cables.

Lab Workflow

  • Connect the Intel® Quark™ SE board to the host PC
  • Check that USB driver is properly installed
  • Run ISSM
  • Update Boot ROM (once per board)
  • Create a new project with the provided source code.
  • Build the project.
  • Flash and Run the project.
  • Observe the result.
  • Debugging.
  • Review the source code

 

 

 

 

 

 

 

 

Lab Instructions

Step 1: Connect the Intel® Quark™ SE board (Atlas Hills).

Connect the board to your PC using the USB Type A to Micro USB Type B cables.

  1. Make sure that your Jumpers and Power Switch are properly set like in the picture below. They will be properly set by default out-of-the-box
  2. Connect to your host machine with the micro-USB cable B to power up your board, to connect with JTAG and to get serial output
  3. Use micro-USB cable C to fully power up the board

 

Step 2: Check the USB driver and COM port

Open Zadig (http://zadig.akeo.ie/) to replace the drivers of Intel Quark SE so they will work properly with ISSM.

 Check Options -> List All Devices.

 

Then you can see Atlas Hills Rev-x (… ) ( Interface 0 ). Choose it and replace driver with WinUSB as you can see in the picture below.

 

Now open Windows Device Manager and make sure there you see a new USB Serial Port under Port (COM & LPT) and Atlas Hills Rev – X (IPN: … ) under Universal Serial Bus Devices.

 

If the Atlas Hills Rev device does not appear or the Universal Serial Bus devices category is missing, the USB driver needs to be installed. To install the driver, navigate to C:\IntelSWTools\ISSM_2016.1.0xx\tools\debugger\driver directory using File Explorer, run the install.bat as Administrator, and answer ‘y’ in the window that will appear[AM2] [KJ3] .

Step 3: Run Intel® System Studio for Microcontrollers

Using File Explorer navigate to C:\IntelSWTools\ISSM_2016.1.0xx directory, and double click on the iss_mcu_ide_eclipse-launcher.bat.

The Intel® System Studio for Microcontrollers will prompt for the workspace location:

It is recommended to click Browse… button here and change the workspace location to your user directory, for example C:\Users\username\Documents\workspace. Click OK button to confirm workspace selection. The Intel® System Studio for Microcontrollers windows will appear as shown on the screenshot below.

 

 

Step 4: Update boot ROM

Note: This step needs to be performed only once per board.

From Intel ISSM menu select Update target ROM… entry as shown on the screenshot below.

The Update target ROM dialog will appear. Make sure that you select the board and project type accordingly. Click Update button to program the ROM to the microcontroller.

Step 5: Create a new project

From the Intel ISSM menu select New Intel ® Project. The Create new Project will appear. Choose Atlas Hills and click Next.

 You can choose between Intel® QMSI(Intel® Quark Microcontroller Software Interface) and Zephyr but this time we will try Intel® QMSI.

Select Intel® Quark as the selected core since this project runs on Intel® Quark core. There are projects run on Arc[AM4] core particularly.

 

Now, name your project as you wish and choose gpio, then click Finish.

 

 

In the Project Explorer window on the left side of Intel® System Studio for Microcontrollers click on the gpio project. Find main.c file and double click on it to open it the editor.

Step 6: Build the project

Click on the Build button (“hammer”   icon) on the toolbar to build the project. Alternatively it is possible to select the build configuration using the drop down menu next to that button. Intel® Systems Studio for Microcontrollers provides two configurations: debug and release. The debug configuration includes symbols in the generated binary files to facilitate debugging. It is the default configuration. The release configuration optimizes code for deployment.

Step 7: Flash and run the project

Click on the drop down menu next to the Run button (“play” icon). Select gpio_new (flashing) from the menu. The Intel® Systems Studio for Microcontrollers [AM5] [DCI6] will recompile the code, and flash it to the microcontroller.

Note: Intel® System Studio for Microcontrollers offers two ways to run the code: The first – gpio_new option assumes that the code had been already programmed to the microcontroller. The second – gpio_new (flashing) option will recompile and re-flash the code. Use this option if the source code had been changed since the last time microcontroller was programmed. This is the option used in this lab step.

Note: The flashing process takes some time. Look for the progress bar at the bottom right corner of the Intel® Systems Studio for Microcontrollers window:

Step 8: Test the project

Set up a jumper cable connecting pin 42 and 40 on header P4. Pin 42 is an output pin which triggers an interrupt on the input pin and pin 40 is configured as an input pin with interrupts enabled.

 

 

Open Terminals view (Window -> Show View -> Terminals ) and open a terminal by clicking on a monitor icon in Terminals view. Choose the right COM port of the board which can be found in Windows Device Manager.  See the following configuration for the rest of the configuration for the terminal connection.

 

In the terminal , you should see messages as the following when you run the example

 

 

Congratulations, you just had completed your first Intel® Quark™ SE project!

Step 9: Debug the project

Click on the drop down menu next to the Debug button (“bug” icon). Select gpio_new from the menu.

Note: Intel® System Studio for Microcontrollers offers two ways to start debugging: The first – gpio_new option assumes that the code had been already programmed to the microcontroller (In this lab it was done in the “Flashing and running the project” step). The second – gpio_new (flashing) option will recompile and re-flash the code. Use this option if the source code had been changed since the last time microcontroller was programmed.

The Intel® Systems Studio for Microcontrollers will ask you about switching to the Debug perspective. Click the Yes button here.

Tip: It is possible to switch between perspectives using the Window -> Open Perspective menu, or by clicking C/C++ or Debug buttons on the Quick Access toolbar:

The Debug perspective will open.

Try using the debug functions described below:

Toggling breakpoints

Right click on the bar on the left from the code line where you want to set or remove a breakpoint, and select the Toggle Breakpoint menu item.

Follow the next steps for this lab:

  • Find the following line in the main.c  (line 102):

QM_PRINTF("GPIO callback - status register = 0x%u\n", status);

  • Right click on the bar from the left of this line, and select the Toggle Breakpoint menu item, as shown on the screenshot below.

 

Controlling the code execution

Use the toolbar buttons shown on the screenshot below, their corresponding shortcut keystrokes (for example F5 – Step Into, F6 – Step Over, F8 – Resume), or the commands from the Run menu to control the code execution.

Follow the next steps for this lab:

  • Click Resume button once. Observe code running till the breakpoint set in the previous step.
  • Press Resume button again to continue running the code.
  • Push Suspend button to stop the code.

These commands also accessible using right click inside the Debug window.

Adding a conditional breakpoint

Conditional breakpoints are useful for suspending the code execution when certain conditions are met. Right click on the bar on the left from the code line where you want to add a conditional breakpoint and select the Add Breakpoint... menu item. The Properties for C/C++ Line Breakpoint dialog will appear. Enter the condition expression in the Condition text box.

Follow the next steps for this lab:

  • Find the following line in the main.c (line 83):

while (!callback_invoked) {

  • Right click on the bar from the left of this line, and select the Add Breakpoint… menu item
  • Set the condition to callback_invoked as shown on the screenshot below, and click OK button.
  • Press Resume button to continue running the code.
  • Press run during the debug session, you will see it stops at line 83 when callback_invoked becomes true and the process escapes from the while loop.

Using EmbSys Registers view

The EmbSys Registers view allows viewing and modifying Intel® Quark™ Microcontroller SE peripheral registers. This feature is useful when debugging on-chip peripherals and their interaction with the external hardware.

Follow the next steps for this lab:

  • Locate the EmbSys Registers window. You might need to enlarge it, so that all fields are visible.
  • In the EmbSys Registers view click on the Peripherals item to open it.
  • Next find and click on the fst_periph_GPIO_reg_i to open the list of GPIO registers.
  • Locate the GPIO_SWPORTA_DDR register and click on it to show the bit fields in this register. This register is the data register for GPIO ports. Bits number 0 to 31 of this register map to the GPIO pins of the microcontroller.

  • Double click on GPIO_SWPORTA_DDR again to activate it. The register will be colored green, and the current value of the register will be shown.
    • In case the current value is not shown it might be necessary to Resume and Suspend the code.
  • Click in the Bin value of the GPIO_SWPORTA_DDR (bits 31-0) bit field. The buttons for each pin indicating the current bits values and the Set button will appear, as shown on the screenshot below.
  • Click on the 6th and 7th from the left bits to change their value to 1. Click on the Set button to send the updated value to the microcontroller. Observe that the LEDs on the board (LED0 and LED1) will light up. This happens because bit 25 and 26 are connected to the on-board LEDs, and setting it to 1 turns on the LEDs.

  • Click on those bits again to change their value back to 0. Click on the Set button to send the updated value to the microcontroller. The LEDs will turn off.

 

Other debug views

There are multiple other debug views are available – feel free to explore them on your own. Here are just some of them:

  • Disassembly view
  • Registers view
  • Memory view

Use Windows -> Show View menu to select the views. Note that the view selection will vary depending on the active perspective.

OpenOCD view

The Intel® System Studio for Microcontroller uses OpenOCD software to interface to the Intel® Quark™ SE through JTAG interface. This software is running in the OpenOCD view. In some cases, for example when board is disconnected and reconnected, it might be necessary to restart OpenOCD. This can be done by clicking the Stop OpenOCD (red “stop” icon) button, and then clicking the Start OpenOCD (green “play” icon) button at the top right corner of the OpenOCD view. It is necessary to restart the debugging session after OpenOCD had been restarted.

 

 

Lab Source Code

How it works

This sample code enables a pin interrupt on a GPIO pin number 40 and gets an input signal from another GPIO pin, pin number 42, through a jumper. Then the interrupt runs the IRS which makes the process escapes a while loop to finally finish its task and print out “Finished : GPIO“.

The GPIO sample configures those I/O pins as following:

  • PIN_OUT is configured for the output mode:

cfg.direction = BIT(PIN_OUT);

  • PIN_INTR is configured as the following

cfg.int_en = BIT(PIN_INTR);       /* Interrupt enabled */

cfg.int_type = BIT(PIN_INTR);     /* Edge sensitive interrupt */

cfg.int_polarity = BIT(PIN_INTR); /* Rising edge */

cfg.int_debounce = BIT(PIN_INTR); /* Debounce enabled */

cfg.int_bothedge = 0x0;            /* Both edge disabled */

cfg.callback = gpio_example_callback;

  • The sample sets the gpio_example_callback function as the interrupt callback:

cfg.callback = gpio_example_callback;

cfg.callback_data = NULL;

  • Requesting the given IRQ and register Interrupt Service Routine to interrupt vector and applying the pin configuration:

qm_irq_request(QM_IRQ_GPIO_0, qm_gpio_isr_0);

qm_gpio_set_config(QM_GPIO_0, &cfg);

 

 

Source Code

#include"qm_gpio.h"

#include"qm_interrupt.h"

#include"qm_isr.h"

 

#include<inttypes.h>

 

/* QMSI GPIO app example

 *

 * This app requires a board to be set up with a jumper cable connecting the

 * pins listed below so the output pin can trigger an interrupt on the

 * input pin. PIN_OUT will be configured as an output pin and PIN_INTR will be

 * configured as an input pin with interrupts

 * enabled.

 *

 * On the Intel(R) Quark(TM) Microcontroller D2000 Development Platform PIN_OUT

 * and PIN_INTR are marked "SSO 10" and "A0".

 * On Quark SE development board, PIN_OUT and PIN_INTR are located on header P4

 * PIN 42 and 40.

 */

#define PIN_OUT 0

#define PIN_INTR 3

 

/* Example callback function */

staticvoidgpio_example_callback(void *, uint32_t);

 

volatile bool callback_invoked;

 

intmain(void)

{

       qm_gpio_port_config_t cfg;

       qm_gpio_state_t state;

 

       QM_PUTS("Starting: GPIO\n");

 

       /* Request IRQ and write GPIO port config */

       cfg.direction = BIT(PIN_OUT);

       cfg.int_en = BIT(PIN_INTR);       /* Interrupt enabled */

       cfg.int_type = BIT(PIN_INTR);     /* Edge sensitive interrupt */

       cfg.int_polarity = BIT(PIN_INTR); /* Rising edge */

       cfg.int_debounce = BIT(PIN_INTR); /* Debounce enabled */

       cfg.int_bothedge = 0x0;            /* Both edge disabled */

       cfg.callback = gpio_example_callback;

       cfg.callback_data = NULL;

       callback_invoked = false;

 

       qm_irq_request(QM_IRQ_GPIO_0, qm_gpio_isr_0);

 

       qm_gpio_set_config(QM_GPIO_0, &cfg);

 

       /* Set PIN_OUT to trigger PIN_INTR interrupt */

       qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

       qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);

 

       while (!callback_invoked) {

       }

 

       if (qm_gpio_read_pin(QM_GPIO_0, PIN_OUT, &state)) {

             QM_PUTS("Error: read pin failed\n");

             return -EIO;

       }

       if (state != QM_GPIO_HIGH) {

             QM_PUTS("Error: pin comparison failed\n");

             return -EIO;

       }

       qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

       QM_PUTS("Finished: GPIO\n");

       return 0;

}

       

voidgpio_example_callback(void *data, uint32_t status)

{

       callback_invoked = true;

       QM_PRINTF("GPIO callback - status register = 0x%u\n", status);

}

 


 [AM1]Block 1: D2000

Block 3: correct naming

Block 8: blinking is not the aim of this sample

 [AM2]Maybe mention that it should be run as an Administrator

 [AM4]ARC is not an Intel core

 [AM5]It is not ISSM actually which compiles and flash

 [DCI6]This is not so critical, if no better expression can be found we can leave it this way

Announcing the Intel® Edison Developer Challenge

$
0
0

For all developers, start-ups and ISVs who have an idea for a product that makes the Internet of Things a reality, look no further.

Intel® has launched a challenge in UK with community partner HW Academy. After 6 months of training developers within the HW Academy community on how to build projects with the Intel® Edison Module, Intel® and HW Academy have teamed up to bring you the Intel® Edison Developer Challenge. By combining great ideas with leading technology, we are hoping to build some prototype projects using the Intel® Edison Module and the Intel® IoT Developer Kit.

Intel® Edison Developer Challenge

Since December 2015, HW Academy have run a series of Intel® Edison beginner workshops in London, UK. The workshops have sold out—usually the same day they launch—and in many cases a waitlist has been in operation. Those developers that attended were presented with an Intel® Edison board, the Intel® IoT Developer Kit and some Intel® technical support in order to learn how to get the board connected to their PC and pulling data from sensors plugged in to the board. In every workshop, there were some people who had buzzers going off, LEDs flashing, temperature being recorded and data being written to an LCD screen. In June, we invited those trained developers to an intermediate workshop where they were exposed to the techniques of connecting the Edison board to the cloud and reporting the data generated by the sensors to a dashboard in the cloud. This experience provided the developers with a foundation of how to develop prototype products for the Internet of Things.

IoT Prototyping

If you are in UK and have a great idea for a project, apply using the website above or follow this link: http://www.hardwareacademy.io/intel-edison-developer-challenge. The 10 best entries will get their own Edison board and Grove* Sensor Kit to build their project, and the best project that is uploaded to Instructables will win £1000 and have their project presented on the Intel® Developer Zone for people to see.

Good Luck!

Application Performance Using Intel® OpenCL™ Driver Diagnostics Sample User's Guide

$
0
0

Intel® SDK for OpenCL™ Applications - Samples

Download Code Samples

Contents

Introduction

This article presents a driver diagnostics sample that demonstrates how to use the Intel® OpenCL™ extension to help get better performance results in applications. The article also discusses the most common mistakes made during application development and describes the diagnostic output (performance hint) feature that tells which behavior is more desirable to execute faster and shows measured time differences.

Motivation

Better application performance comes from code quality and knowledge. To help you improve your code, the OpenCL Driver provides a feature that helps you understand how your implementation impacts performance. We can find many examples showing how to write good code, but how can we check whether our implementation fits driver expectations? A returned hint points out which API call can cause performance drop and tells how to fix it. It works on selected context so we can use it as an automated bug finder.

How Driver Diagnostics Works

Types of hints

You can use three types of hints, depending on needs:

  1. BAD
    This hint is provided when a specific execution can cause performance drop. A potential solution to the problem is also described. Example: Non-zero copy buffer.
  2. NEUTRAL
    There is a potential performance impact, but it’s expected. This hint may be also used to inform the user about specific actions.
  3. GOOD
    In contrast to the BAD type of hint, this hint suggests the right approach. Example: zero copy buffer.

Each level is described as a flag that is passed as a value of the

CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL parameter during the clCreateContext call:

CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL

CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL

CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL

Receiving a hint

Information about the enabling feature and desired hint level must be passed as a parameter during the clCreateContext call. Driver output is provided by the callback function which is also passed to the same API call.

The example below shows how to create the proper context and receive the hint string.

void CL_CALLBACK NotifyFunction( const char * pErrInfo, const void * pPrivateInfo, size_t size, void * pUserData )
{
    if( pErrInfo != NULL )
    {
        PrintHint( pErrInfo ); // Parse hint
    }
};

void SampleClass::SampleFcn( cl_device_id deviceID )
{
    cl_int ErrorCode;
    m_pfnNotify = NotifyFunction;

    m_hintLevel = CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL | CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL;

    cl_context_properties properties[ ] =
    {
        CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL, (cl_context_properties)m_hintLevel,
        0
    };

    cl_context context = clCreateContext( properties, 1, &deviceID, m_pfnNotify, m_UserData, &Error );
    checkError( Error );

    Execute();
}

Output

Each time the driver decides that a hint should be provided, the NotifyFunction() is executed and pErrInfo is the hint string. We should also remember mutual exclusion when operating on a string. Example: Inserting to a std container.

Examples for BAD and GOOD levels:

Performance hint: clCreateBuffer with pointer 3195c24 and size 3900 doesn't meet alignment restrictions. Size should be aligned to 4096 bytes and pointer should be aligned to 4096. Buffer is not sharing the same physical memory with CPU.

Performance hint: clCreateBuffer with pointer 30d5000 and size 4096 meets alignment restrictions and buffer will share the same physical memory with CPU.

As we can see, the provided hints show which API call is affected and how to fix the problem (for the BAD case). In most scenarios, a BAD hint has an opposite GOOD hint that confirms that the problem doesn’t occur—but not always. Sometimes when a BAD hint disappears, we won’t see any confirmation from a GOOD hint.

Sample Prerequisites

You must have the latest Intel® Graphics Driver supporting the cl_intel_driver_diagnostics extension for the OpenCL GPU Device (the device needs to support the extension) and Intel SDK for OpenCL installed.

The code provided is not OS-specific. To run the sample you need to prepare it using cmake (version >= 3.1.0). There is a CMakeLists.txt file in the sample directory:

> cmake CMakeLists.txt

Then you can use the generated files by CMake* to build a sample (for example, using Microsoft Visual Studio*).

Sample Output

We can select up to three test scenarios to execute: buffers, kernels, enqueues. Each scenario has its own test set. And each test presents similar output:

Testing bad case…
[Received hints]

Testing good case…
[Received hints]

Result: Bad case [x] us – Good case [y] us – BAD/GOOD [x]/[y]

The sample shows two opposite cases where we can see potential performance gain. Time is measured before the affected call and after clFinish() to measure the actual work.

Controlling The Sample

Since this feature is Intel-specific for the GPU driver you don’t need to select the platform or device manually.

The sample executable is a console application. Use the following command-line arguments for the sample control:

OptionDescription
-h, -helpShow help text and exit.
-test_scenario_buffersExecute “buffers” scenario.
-test_scenario_kernelsExecute “kernels” scenario.
-test_scenario_enqueuesExecute “enqueues” scenario.
-print_all_hintsPrint all received hints if used. Otherwise only expected hints for specific case will be shown.
-print_descriptionsPrint description for currently executing test case if set.

APIs Used

This sample uses the following APIs:

  • clBuildProgram
  • clCreateBuffer
  • clCreateCommandQueue
  • clCreateContext
  • clCreateKernel
  • clCreateProgramWithSource
  • clEnqueueMapBuffer
  • clEnqueueNDRangeKernel
  • clEnqueueReadBuffer
  • clEnqueueUnmapMemObject
  • clEnqueueWriteBuffer
  • clFinish
  • clGetDeviceIDs
  • clGetDeviceInfo
  • clGetPlatformIDs
  • clGetPlatformInfo
  • clReleaseCommandQueue
  • clReleaseContext
  • clReleaseKernel
  • clReleaseMemObject
  • clReleaseProgram
  • clSetKernelArg

References

Half the footprint, twice the speed: Accelerating performance for server-side PHP 7

$
0
0

Close collaboration between Intel and the PHP community enables new hardware features that improve processing efficiency, increase execution speed, and optimize core software of interpreted languages — significantly boosting PHP 7 performance on Intel® Xeon® processors

Choosing the right combination of hardware and software is one of the simplest and most effective ways to improve performance for PHP-based applications. To this end, Intel has shared knowledge, insight, and hints with the PHP community to help boost PHP performance and optimize this popular language on Intel® Xeon® processors.

In addition, the software performance of PHP 7 sees a boost with each new generation of Intel® Architecture (IA), which introduces features that increase hardware execution efficiency. At the source level, Intel has also worked extensively to “tune” processors. This increases execution efficiency and performance even further — performance that is particularly important for PHP and other interpreted languages that have a large footprint.

These collaborative efforts have enabled two key advances for PHP 7 over the previous version (PHP 5): a much smaller memory footprint, and a dramatic 2x performance gain for real-world applications on Intel Xeon processors.


Making your VR application more realistic – adding complex physics to games

$
0
0

Nowadays, VR is welcomed by lots of developers, OEMs, and end users. People enjoy VR experience as they can be immersive in a virtual world. In that situation, physics plays an even more important role than before because it gives users a more real experience while in the virtual world. In that case, the physics provided by original games engines may not be enough. Developers need to developer together with game engines and professional physics engine. This whitepaper will show you how to develop with Unreal and bullet physics? Please refer to the attachments to reach full paper. https://software.intel.com/system/files/managed/89/d9/VR%20optimizations-4.pdf

 

Predicting user activity in devices using an accelerometer with the Intel Edison

$
0
0

 

This project describes how to recognize certain types of human physical activities using acceleration data generated from the ADXL345 accelerometer connected to the Intel Edison.

Human activity recognition has a wide range of applications especially in wearables. The data collected can be used monitoring patient activity, exercise patterns in athletes, fitness tracking and so on.

We will be using support vector machine learning algorithm to achieve this. The project is implemented using the LIBSVM library and done separately in both Python and node.js.

The set of activities to be recognized are running, walking, going up/down a flight of stairs and resting. We collect the accelerometer data over a set of intervals, extract the features which in this case are the acceleration values along the x,y and z axes. We then use this data for building a training model that will do the activity classification.

The project code can be downloaded from  Downloadapplication/zipDownload

Hardware Implementation.

The diagram below shows the pin connection for the ADXL345 to the Intel Edison.

edison to adxl345 pin connection

Part 1. Python Implementation.

Setting up LIBSVM

Download the LIBSVM library and transfer the  LibSVM  zipped folder to the Edison board root directory using WINSCP. Then extract it by running:

tar –xzf libsvm-3.21.tar.gz

Run  make in libsvm-3.21 directory

Run make in libsvm-3.21/python directory

Create the predict-activity.py python script in the libsvm-3.21/python directory

Reading data from the ADXL345 accelerometer

import pyupm_adxl345 as adxl345
# Create an I2C accelerometer object
adxl = adxl345.Adxl345(0)
while True:
    adxl.update() # Update the data
    raw = adxl.getRawValues() # Read raw sensor data
    force = adxl.getAcceleration() # Read acceleration force (g)

    forceX=format(force[0],'.2f')
    forceY=format(force[1],'.2f')
    forceZ=format(force[2],'.2f')

sleep(2)

Classifying the various activities

The training file contains instances of the various activities classified as;

0-walking

1-running/jogging

2-up/down staircase

3-resting

Below is the screenshot of a small section of the training file

small section of training data screenshot

Running a grid search to determine the best value for C:

The parameter C controls the tradeoff between errors of the SVM on training data and margin maximization. C is used during the training phase and says how much outliers are taken into account in calculating Support Vectors. 

from svmutil import *
import numpy as nu

param = svm_parameter("-q -h 0")
y, x = svm_read_problem('activity.ds')
problem = svm_problem(y[:100], x[:100])
results = []
for c in range(-10,20):
  for g in range(-10,5):
    param.C, param.gamma = 2**c, 2**g
    m = svm_train(problem,param)
    p_lbl, p_acc, p_val = svm_predict(y[100:],x[100:],m)
    results.append([param.C, param.gamma, p_acc[0]])

bestIdx = nu.argmax(nu.array(results)[:,2])

print results[bestIdx]

grid search result

Classifying various user activities

#load the LIBSVM shared library:
from svmutil import *
#Construct an svm_problem instance where the activity.ds is the dataset with the training data
y, x = svm_read_problem('activity.ds')
where y is the tuple of labels representing the various activities and x is a tuple of data instances representing acceleration values from x,y and z axes

m = svm_train(y[0:], x[0:], '-c 0.03125 -h 0 -b 1 -q')
#y[0:] and x[0:] means we train the model on the whole dataset array from the first instance[0] to the last
#-h disable shrinking heuristics
#-c : set the cost parameter C of C-SVC
#-q: quiet mode (no outputs)

values=[[float(forceX),float(forceY), float(forceZ)]]
#forceX,forceY and forceZ are data instances of the accelerometer values in x,y,z axes

 p_labels,p_acc,p_values = svm_predict([0]*len(values),values,m])
#pass the accelerometer values for prediction in the svm_predict() method which returns
#p_labels: a list of predicted labels   p_acc: a tuple including accuracy and p_values: a list of decision values or probability estimates (if '-b 1' is specified)
print p_labels
#output the predicted labels to represent the predicted activity

classification result screenshot

Part 2. Node.Js Implementation

Create a new project directory in the board’s home root folder and install node-svm:

npm install node-svm

Copy the build and lib folder from the node-modules/node-svm to the project directory. 

Next install the packages required by node-svm by running:

npm install <package-name>

The packages are Stringify-object, Mout, Graceful-fs, Optimist, Osenv, Numeric, Q and underscore.

Reading data from the ADXL345 accelerometer

Reading data from the ADXL345 accelerometer
var adxl345 = require('jsupm_adxl345');
var adxl = new adxl345.Adxl345(0);

setInterval(function()
{
    adxl.update(); // Update the data
    var raw = adxl.getRawValues(); // Read raw sensor data
    var force = adxl.getAcceleration(); // Read acceleration force (g)
    var rawvalues = raw.getitem(0) + "" + raw.getitem(1) + "" + raw.getitem(2);
    //console.log("Raw Values: " + rawvalues);
    var forceX=force.getitem(0).toFixed(2);
    var forceY=force.getitem(1).toFixed(2);
    var forceZ=force.getitem(2).toFixed(2);

}, 2000);

We can now write the code to classify user activity using the value of c we determined from running the grid search using Python in part 1.

var so = require('stringify-object');
var svm = require('./lib');
var numeric = require('numeric');
var fs = require('fs');
var fileName = './activity.ds';

//create the classifier
var clf = new svm.CSVC({
    c: 0.03125,
    normalize: false,
    reduce: false,
});

//Build the training model
svm.read(fileName)
    .then(function (dataset) {
        return clf.train(dataset)
            .progress(function (progress) {
                console.log('training progress: %d%', Math.round(progress * 100));
            });
    })
    .spread(function (model, report) {
        console.log('SVM trained. \nReport:\n%s', so(report));
    }).done(function () {
        console.log('done.');
    });

//Classify data instance at some interval
var prediction=clf.predictSync([forceX, forceY, forceZ]);
var probability=clf.predictProbabilitiesSync([forceX, forceY, forceZ]);
console.log(prediction);

console output for node.js program

Summary

The project covers how to determine the training parameters of the classifier using a grid search and running the classifier to be able to accurately predict various activities using LIBSVM in both Python and node.js. SVMs require a lot for processing power and memory; the Edison board delivers effectively on these requirements thus making the project a success. What will you make?

 

Intel® XDK FAQs - General

$
0
0

How can I get started with Intel XDK?

There are plenty of videos and articles that you can go through here to get started. You could also start with some of our demo apps. It may also help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, which will help you understand some of the differences between developing for a traditional server-based environment and developing for the Intel XDK hybrid Cordova app environment.

Having prior understanding of how to program using HTML, CSS and JavaScript* is crucial to using the Intel XDK. The Intel XDK is primarily a tool for visualizing, debugging and building an app package for distribution.

You can do the following to access our demo apps:

  • Select Project tab
  • Select "Start a New Project"
  • Select "Samples and Demos"
  • Create a new project from a demo

If you have specific questions following that, please post it to our forums.

How do I convert my web app or web site into a mobile app?

The Intel XDK creates Cordova mobile apps (aka PhoneGap apps). Cordova web apps are driven by HTML5 code (HTML, CSS and JavaScript). There is no web server in the mobile device to "serve" the HTML pages in your Cordova web app, the main program resources required by your Cordova web app are file-based, meaning all of your web app resources are located within the mobile app package and reside on the mobile device. Your app may also require resources from a server. In that case, you will need to connect with that server using AJAX or similar techniques, usually via a collection of RESTful APIs provided by that server. However, your app is not integrated into that server, the two entities are independent and separate.

Many web developers believe they should be able to include PHP or Java code or other "server-based" code as an integral part of their Cordova app, just as they do in a "dynamic web app." This technique does not work in a Cordova web app, because your app does not reside on a server, there is no "backend"; your Cordova web app is a "front-end" HTML5 web app that runs independent of any servers. See the following articles for more information on how to move from writing "multi-page dynamic web apps" to "single-page Cordova web apps":

Can I use an external editor for development in Intel® XDK?

Yes, you can open your files and edit them in your favorite editor. However, note that you must use Brackets* to use the "Live Layout Editing" feature. Also, if you are using App Designer (the UI layout tool in Intel XDK) it will make many automatic changes to your index.html file, so it is best not to edit that file externally at the same time you have App Designer open.

Some popular editors among our users include:

  • Sublime Text* (Refer to this article for information on the Intel XDK plugin for Sublime Text*)
  • Notepad++* for a lighweight editor
  • Jetbrains* editors (Webstorm*)
  • Vim* the editor

How do I get code refactoring capability in Brackets* (the Intel XDK code editor)?

...to be written...

Why doesn’t my app show up in Google* play for tablets?

...to be written...

What is the global-settings.xdk file and how do I locate it?

global-settings.xdk contains information about all your projects in the Intel XDK, along with many of the settings related to panels under each tab (Emulate, Debug etc). For example, you can set the emulator to auto-refresh or no-auto-refresh. Modify this file at your own risk and always keep a backup of the original!

You can locate global-settings.xdk here:

  • Mac OS X*
    ~/Library/Application Support/XDK/global-settings.xdk
  • Microsoft Windows*
    %LocalAppData%\XDK
  • Linux*
    ~/.config/XDK/global-settings.xdk

If you are having trouble locating this file, you can search for it on your system using something like the following:

  • Windows:
    > cd /
    > dir /s global-settings.xdk
  • Mac and Linux:
    $ sudo find / -name global-settings.xdk

When do I use the intelxdk.js, xhr.js and cordova.js libraries?

The intelxdk.js and xhr.js libraries were only required for use with the Intel XDK legacy build tiles (which have been retired). The cordova.js library is needed for all Cordova builds. When building with the Cordova tiles, any references to intelxdk.js and xhr.js libraries in your index.html file are ignored.

How do I get my Android (and Crosswalk) keystore file?

New with release 3088 of the Intel XDK, you may now download your build certificates (aka keystore) using the new certificate manager that is built into the Intel XDK. Please read the initial paragraphs of Managing Certificates for your Intel XDK Account and the section titled "Convert a Legacy Android Certificate" in that document, for details regarding how to do this.

It may also help to review this short, quick overview video (there is no audio) that shows how you convert your existing "legacy" certificates to the "new" format that allows you to directly manage your certificates using the certificate management tool that is built into the Intel XDK. This conversion process is done only once.

If the above fails, please send an email to html5tools@intel.com requesting help. It is important that you send that email from the email address associated with your Intel XDK account.

How do I rename my project that is a duplicate of an existing project?

See this FAQ: How do I make a copy of an existing Intel XDK project?

How do I recover when the Intel XDK hangs or won't start?

  • If you are running Intel XDK on Windows* it must be Windows* 7 or higher. It will not run reliably on earlier versions.
  • Delete the "project-name.xdk" file from the project directory that Intel XDK is trying to open when it starts (it will try to open the project that was open during your last session), then try starting Intel XDK. You will have to "import" your project into Intel XDK again. Importing merely creates the "project-name.xdk" file in your project directory and adds that project to the "global-settings.xdk" file.
  • Rename the project directory Intel XDK is trying to open when it starts. Create a new project based on one of the demo apps. Test Intel XDK using that demo app. If everything works, restart Intel XDK and try it again. If it still works, rename your problem project folder back to its original name and open Intel XDK again (it should now open the sample project you previously opened). You may have to re-select your problem project (Intel XDK should have forgotten that project during the previous session).
  • Clear Intel XDK's program cache directories and files.

    On a Windows machine this can be done using the following on a standard command prompt (administrator is not required):

    > cd %AppData%\..\Local\XDK
    > del *.* /s/q

    To locate the "XDK cache" directory on [OS X*] and [Linux*] systems, do the following:

    $ sudo find / -name global-settings.xdk
    $ cd <dir found above>
    $ sudo rm -rf *

    You might want to save a copy of the "global-settings.xdk" file before you delete that cache directory and copy it back before you restart Intel XDK. Doing so will save you the effort of rebuilding your list of projects. Please refer to this question for information on how to locate the global-settings.xdk file.
  • If you save the "global-settings.xdk" file and restored it in the step above and you're still having hang troubles, try deleting the directories and files above, along with the "global-settings.xdk" file and try it again.
  • Do not store your project directories on a network share (Intel XDK currently has issues with network shares that have not yet been resolved). This includes folders shared between a Virtual machine (VM) guest and its host machine (for example, if you are running Windows* in a VM running on a Mac* host). This network share issue is a known issue with a fix request in place.
  • There have also been issues with running behind a corporate network proxy or firewall. To check them try running Intel XDK from your home network where, presumably, you have a simple NAT router and no proxy or firewall. If things work correctly there then your corporate firewall or proxy may be the source of the problem.
  • Issues with Intel XDK account logins can also cause Intel XDK to hang. To confirm that your login is working correctly, go to the Intel XDK App Center and confirm that you can login with your Intel XDK account. While you are there you might also try deleting the offending project(s) from the App Center.

If you can reliably reproduce the problem, please send us a copy of the "xdk.log" file that is stored in the same directory as the "global-settings.xdk" file to html5tools@intel.com.

Is Intel XDK an open source project? How can I contribute to the Intel XDK community?

No, It is not an open source project. However, it utilizes many open source components that are then assembled into Intel XDK. While you cannot contribute directly to the Intel XDK integration effort, you can contribute to the many open source components that make up Intel XDK.

The following open source components are the major elements that are being used by Intel XDK:

  • Node-Webkit
  • Chromium
  • Ripple* emulator
  • Brackets* editor
  • Weinre* remote debugger
  • Crosswalk*
  • Cordova*
  • App Framework*

How do I configure Intel XDK to use 9 patch png for Android* apps splash screen?

Intel XDK does support the use of 9 patch png for Android* apps splash screen. You can read up more at https://software.intel.com/en-us/xdk/articles/android-splash-screens-using-nine-patch-png on how to create a 9 patch png image and link to an Intel XDK sample using 9 patch png images.

How do I stop AVG from popping up the "General Behavioral Detection" window when Intel XDK is launched?

You can try adding nw.exe as the app that needs an exception in AVG.

What do I specify for "App ID" in Intel XDK under Build Settings?

Your app ID uniquely identifies your app. For example, it can be used to identify your app within Apple’s application services allowing you to use things like in-app purchasing and push notifications.

Here are some useful articles on how to create an App ID:

Is it possible to modify the Android Manifest or iOS plist file with the Intel XDK?

You cannot modify the AndroidManifest.xml file directly with our build system, as it only exists in the cloud. However, you may do so by creating a dummy plugin that only contains a plugin.xml file containing directives that can be used to add lines to the AndroidManifest.xml file during the build process. In essence, you add lines to the AndroidManifest.xml file via a local plugin.xml file. Here is an example of a plugin that does just that:

<?xml version="1.0" encoding="UTF-8"?><plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="my-custom-intents-plugin" version="1.0.0"><name>My Custom Intents Plugin</name><description>Add Intents to the AndroidManifest.xml</description><license>MIT</license><engines><engine name="cordova" version=">=3.0.0" /></engines><!-- android --><platform name="android"><config-file target="AndroidManifest.xml" parent="/manifest/application"><activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:launchMode="singleTop" android:name="testa" android:theme="@android:style/Theme.Black.NoTitleBar"><intent-filter><action android:name="android.intent.action.SEND" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="*/*" /></intent-filter></activity></config-file></platform></plugin>

You can inspect the AndroidManifest.xml created in an APK, using apktool with the following command line:

$ apktool d my-app.apk
$ cd my-app
$ more AndroidManifest.xml

This technique exploits the config-file element that is described in the Cordova Plugin Specification docs and can also be used to add lines to iOS plist files. See the Cordova plugin documentation link for additional details.

Here is an example of such a plugin for modifying the iOS plist file, specifically for adding a BIS key to the plist file:

<?xml version="1.0" encoding="UTF-8"?><plugin
    xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="my-custom-bis-plugin"
    version="0.0.2"><name>My Custom BIS Plugin</name><description>Add BIS info to iOS plist file.</description><license>BSD-3</license><preference name="BIS_KEY" /><engines><engine name="cordova" version=">=3.0.0" /></engines><!-- ios --><platform name="ios"><config-file target="*-Info.plist" parent="CFBundleURLTypes"><array><dict><key>ITSAppUsesNonExemptEncryption</key><true/><key>ITSEncryptionExportComplianceCode</key><string>$BIS_KEY</string></dict></array></config-file></platform></plugin>

How can I share my Intel XDK app build?

You can send a link to your project via an email invite from your project settings page. However, a login to your account is required to access the file behind the link. Alternatively, you can download the build from the build page, onto your workstation, and push that built image to some location from which you can send a link to that image.

Why does my iOS build fail when I am able to test it successfully on a device and the emulator?

Common reasons include:

  • Your App ID specified in the project settings do not match the one you specified in Apple's developer portal.
  • The provisioning profile does not match the cert you uploaded. Double check with Apple's developer site that you are using the correct and current distribution cert and that the provisioning profile is still active. Download the provisioning profile again and add it to your project to confirm.
  • In Project Build Settings, your App Name is invalid. It should be modified to include only alpha, space and numbers.

How do I add multiple domains in Domain Access?

Here is the primary doc source for that feature.

If you need to insert multiple domain references, then you will need to add the extra references in the intelxdk.config.additions.xml file. This StackOverflow entry provides a basic idea and you can see the intelxdk.config.*.xml files that are automatically generated with each build for the <access origin="xxx" /> line that is generated based on what you provide in the "Domain Access" field of the "Build Settings" panel on the Project Tab.

How do I build more than one app using the same Apple developer account?

On Apple developer, create a distribution certificate using the "iOS* Certificate Signing Request" key downloaded from Intel XDK Build tab only for the first app. For subsequent apps, reuse the same certificate and import this certificate into the Build tab like you usually would.

How do I include search and spotlight icons as part of my app?

Please refer to this article in the Intel XDK documentation. Create anintelxdk.config.additions.xml file in your top level directory (same location as the otherintelxdk.*.config.xml files) and add the following lines for supporting icons in Settings and other areas in iOS*.

<!-- Spotlight Icon --><icon platform="ios" src="res/ios/icon-40.png" width="40" height="40" /><icon platform="ios" src="res/ios/icon-40@2x.png" width="80" height="80" /><icon platform="ios" src="res/ios/icon-40@3x.png" width="120" height="120" /><!-- iPhone Spotlight and Settings Icon --><icon platform="ios" src="res/ios/icon-small.png" width="29" height="29" /><icon platform="ios" src="res/ios/icon-small@2x.png" width="58" height="58" /><icon platform="ios" src="res/ios/icon-small@3x.png" width="87" height="87" /><!-- iPad Spotlight and Settings Icon --><icon platform="ios" src="res/ios/icon-50.png" width="50" height="50" /><icon platform="ios" src="res/ios/icon-50@2x.png" width="100" height="100" />

For more information related to these configurations, visit http://cordova.apache.org/docs/en/3.5.0/config_ref_images.md.html#Icons%20and%20Splash%20Screens.

For accurate information related to iOS icon sizes, visit https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html

NOTE: The iPhone 6 icons will only be available if iOS* 7 or 8 is the target.

Cordova iOS* 8 support JIRA tracker: https://issues.apache.org/jira/browse/CB-7043

Does Intel XDK support Modbus TCP communication?

No, since Modbus is a specialized protocol, you need to write either some JavaScript* or native code (in the form of a plugin) to handle the Modbus transactions and protocol.

How do I sign an Android* app using an existing keystore?

New with release 3088 of the Intel XDK, you may now import your existing keystore into Intel XDK using the new certificate manager that is built into the Intel XDK. Please read the initial paragraphs of Managing Certificates for your Intel XDK Account and the section titled "Import an Android Certificate Keystore" in that document, for details regarding how to do this.

If the above fails, please send an email to html5tools@intel.com requesting help. It is important that you send that email from the email address associated with your Intel XDK account.

How do I build separately for different Android* versions?

Under the Projects Panel, you can select the Target Android* version under the Build Settings collapsible panel. You can change this value and build your application multiple times to create numerous versions of your application that are targeted for multiple versions of Android*.

How do I display the 'Build App Now' button if my display language is not English?

If your display language is not English and the 'Build App Now' button is proving to be troublesome, you may change your display language to English which can be downloaded by a Windows* update. Once you have installed the English language, proceed to Control Panel > Clock, Language and Region > Region and Language > Change Display Language.

How do I update my Intel XDK version?

When an Intel XDK update is available, an Update Version dialog box lets you download the update. After the download completes, a similar dialog lets you install it. If you did not download or install an update when prompted (or on older versions), click the package icon next to the orange (?) icon in the upper-right to download or install the update. The installation removes the previous Intel XDK version.

How do I import my existing HTML5 app into the Intel XDK?

If your project contains an Intel XDK project file (<project-name>.xdk) you should use the "Open an Intel XDK Project" option located at the bottom of the Projects List on the Projects tab (lower left of the screen, round green "eject" icon, on the Projects tab). This would be the case if you copied an existing Intel XDK project from another system or used a tool that exported a complete Intel XDK project.

If your project does not contain an Intel XDK project file (<project-name>.xdk) you must "import" your code into a new Intel XDK project. To import your project, use the "Start a New Project" option located at the bottom of the Projects List on the Projects tab (lower left of the screen, round blue "plus" icon, on theProjects tab). This will open the "Samples, Demos and Templates" page, which includes an option to "Import Your HTML5 Code Base." Point to the root directory of your project. The Intel XDK will attempt to locate a file named index.html in your project and will set the "Source Directory" on the Projects tab to point to the directory that contains this file.

If your imported project did not contain an index.html file, your project may be unstable. In that case, it is best to delete the imported project from the Intel XDK Projects tab ("x" icon in the upper right corner of the screen), rename your "root" or "main" html file to index.html and import the project again. Several components in the Intel XDK depend on this assumption that the main HTML file in your project is named index.hmtl. See Introducing Intel® XDK Development Tools for more details.

It is highly recommended that your "source directory" be located as a sub-directory inside your "project directory." This insures that non-source files are not included as part of your build package when building your application. If the "source directory" and "project directory" are the same it results in longer upload times to the build server and unnecessarily large application executable files returned by the build system. See the following images for the recommended project file layout.

I am unable to login to App Preview with my Intel XDK password.

On some devices you may have trouble entering your Intel XDK login password directly on the device in the App Preview login screen. In particular, sometimes you may have trouble with the first one or two letters getting lost when entering your password.

Try the following if you are having such difficulties:

  • Reset your password, using the Intel XDK, to something short and simple.

  • Confirm that this new short and simple password works with the XDK (logout and login to the Intel XDK).

  • Confirm that this new password works with the Intel Developer Zone login.

  • Make sure you have the most recent version of Intel App Preview installed on your devices. Go to the store on each device to confirm you have the most recent copy of App Preview installed.

  • Try logging into Intel App Preview on each device with this short and simple password. Check the "show password" box so you can see your password as you type it.

If the above works, it confirms that you can log into your Intel XDK account from App Preview (because App Preview and the Intel XDK go to the same place to authenticate your login). When the above works, you can go back to the Intel XDK and reset your password to something else, if you do not like the short and simple password you used for the test.

How do I completely uninstall the Intel XDK from my system?

Take the following steps to completely uninstall the XDK from your Windows system:

  • From the Windows Control Panel, remove the Intel XDK, using the Windows uninstall tool.

  • Then:
    > cd %LocalAppData%\Intel\XDK
    > del *.* /s/q

  • Then:
    > cd %LocalAppData%\XDK
    > copy global-settings.xdk %UserProfile%
    > del *.* /s/q
    > copy %UserProfile%\global-settings.xdk .

  • Then:
    -- Goto xdk.intel.com and select the download link.
    -- Download and install the new XDK.

To do the same on a Linux or Mac system:

  • On a Linux machine, run the uninstall script, typically /opt/intel/XDK/uninstall.sh.
     
  • Remove the directory into which the Intel XDK was installed.
    -- Typically /opt/intel or your home (~) directory on a Linux machine.
    -- Typically in the /Applications/Intel XDK.app directory on a Mac.
     
  • Then:
    $ find ~ -name global-settings.xdk
    $ cd <result-from-above> (for example ~/Library/Application Support/XDK/ on a Mac)
    $ cp global-settings.xdk ~
    $ rm -Rf *
    $ mv ~/global-settings.xdk .

     
  • Then:
    -- Goto xdk.intel.com and select the download link.
    -- Download and install the new XDK.

Is there a tool that can help me highlight syntax issues in Intel XDK?

Yes, you can use the various linting tools that can be added to the Brackets editor to review any syntax issues in your HTML, CSS and JS files. Go to the "File > Extension Manager..." menu item and add the following extensions: JSHint, CSSLint, HTMLHint, XLint for Intel XDK. Then, review your source files by monitoring the small yellow triangle at the bottom of the edit window (a green check mark indicates no issues).

How do I delete built apps and test apps from the Intel XDK build servers?

You can manage them by logging into: https://appcenter.html5tools-software.intel.com/csd/controlpanel.aspx. This functionality will eventually be available within Intel XDK after which access to app center will be removed.

I need help with the App Security API plugin; where do I find it?

Visit the primary documentation book for the App Security API and see this forum post for some additional details.

When I install my app or use the Debug tab Avast antivirus flags a possible virus, why?

If you are receiving a "Suspicious file detected - APK:CloudRep [Susp]" message from Avast anti-virus installed on your Android device it is due to the fact that you are side-loading the app (or the Intel XDK Debug modules) onto your device (using a download link after building or by using the Debug tab to debug your app), or your app has been installed from an "untrusted" Android store. See the following official explanation from Avast:

Your application was flagged by our cloud reputation system. "Cloud rep" is a new feature of Avast Mobile Security, which flags apks when the following conditions are met:

  1. The file is not prevalent enough; meaning not enough users of Avast Mobile Security have installed your APK.
  2. The source is not an established market (Google Play is an example of an established market).

If you distribute your app using Google Play (or any other trusted market) your users should not see any warning from Avast.

Following are some of the Avast anti-virus notification screens you might see on your device. All of these are perfectly normal, they are due to the fact that you must enable the installation of "non-market" apps in order to use your device for debug and the App IDs associated with your never published app or the custom debug modules that the Debug tab in the Intel XDK builds and installs on your device will not be found in a "established" (aka "trusted") market, such as Google Play.

If you choose to ignore the "Suspicious app activity!" threat you will not receive a threat for that debug module any longer. It will show up in the Avast 'ignored issues' list. Updates to an existing, ignored, custom debug module should continue to be ignored by Avast. However, new custom debug modules (due to a new project App ID or a new version of Crosswalk selected in your project's Build Settings) will result in a new warning from the Avast anti-virus tool.

  

  

How do I add a Brackets extension to the editor that is part of the Intel XDK?

The number of Brackets extensions that are provided in the built-in edition of the Brackets editor are limited to insure stability of the Intel XDK product. Not all extensions are compatible with the edition of Brackets that is embedded within the Intel XDK. Adding incompatible extensions can cause the Intel XDK to quit working.

Despite this warning, there are useful extensions that have not been included in the editor and which can be added to the Intel XDK. Adding them is temporary, each time you update the Intel XDK (or if you reinstall the Intel XDK) you will have to "re-add" your Brackets extension. To add a Brackets extension, use the following procedure:

  • exit the Intel XDK
  • download a ZIP file of the extension you wish to add
  • on Windows, unzip the extension here:
    %LocalAppData%\Intel\XDK\xdk\brackets\b\extensions\dev
  • on Mac OS X, unzip the extension here:
    /Applications/Intel\ XDK.app/Contents/Resources/app.nw/brackets/b/extensions/dev
  • start the Intel XDK

Note that the locations given above are subject to change with new releases of the Intel XDK.

Why does my app or game require so many permissions on Android when built with the Intel XDK?

When you build your HTML5 app using the Intel XDK for Android or Android-Crosswalk you are creating a Cordova app. It may seem like you're not building a Cordova app, but you are. In order to package your app so it can be distributed via an Android store and installed on an Android device, it needs to be built as a hybrid app. The Intel XDK uses Cordova to create that hybrid app.

A pure Cordova app requires the NETWORK permission, it's needed to "jump" between your HTML5 environment and the native Android environment. Additional permissions will be added by any Cordova plugins you include with your application; which permissions are includes are a function of what that plugin does and requires.

Crosswalk for Android builds also require the NETWORK permission, because the Crosswalk image built by the Intel XDK includes support for Cordova. In addition, current versions of Crosswalk (12 and 14 at the time this FAQ was written)also require NETWORK STATE and WIFI STATE. There is an extra permission in some versions of Crosswalk (WRITE EXTERNAL STORAGE) that is only needed by the shared model library of Crosswalk, we have asked the Crosswalk project to remove this permission in a future Crosswalk version.

If you are seeing more than the following five permissions in your XDK-built Crosswalk app:

  • android.permission.INTERNET
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE

then you are seeing permissions that have been added by some plugins. Each plugin is different, so there is no hard rule of thumb. The two "default" core Cordova plugins that are added by the Intel XDK blank templates (device and splash screen) do not require any Android permissions.

BTW: the permission list above comes from a Crosswalk 14 build. Crosswalk 12 builds do not included the last permission; it was added when the Crosswalk project introduced the shared model library option, which started with Crosswalk 13 (the Intel XDK does not support 13 builds).

How do I make a copy of an existing Intel XDK project?

If you just need to make a backup copy of an existing project, and do not plan to open that backup copy as a project in the Intel XDK, do the following:

  • Exit the Intel XDK.
  • Copy the entire project directory:
    • on Windows, use File Explorer to "right-click" and "copy" your project directory, then "right-click" and "paste"
    • on Mac use Finder to "right-click" and then "duplicate" your project directory
    • on Linux, open a terminal window, "cd" to the folder that contains your project, and type "cp -a old-project/ new-project/" at the terminal prompt (where "old-project/" is the folder name of your existing project that you want to copy and "new-project/" is the name of the new folder that will contain a copy of your existing project)

If you want to use an existing project as the starting point of a new project in the Intel XDK. The process described below will insure that the build system does not confuse the ID in your old project with that stored in your new project. If you do not follow the procedure below you will have multiple projects using the same project ID (a special GUID that is stored inside the Intel XDK <project-name>.xdk file in the root directory of your project). Each project in your account must have a unique project ID.

  • Exit the Intel XDK.
  • Make a copy of your existing project using the process described above.
  • Inside the new project that you made (that is, your new copy of your old project), make copies of the <project-name>.xdk file and <project-name>.xdke files and rename those copies to something like project-new.xdk and project-new.xdke (anything you like, just something different than the original project name, preferably the same name as the new project folder in which you are making this new project).
  • Using a TEXT EDITOR (only) (such as Notepad or Sublime or Brackets or some other TEXT editor), open your new "project-new.xdk" file (whatever you named it) and find the projectGuid line, it will look something like this:
    "projectGuid": "a863c382-ca05-4aa4-8601-375f9f209b67",
  • Change the "GUID" to all zeroes, like this: "00000000-0000-0000-000000000000"
  • Save the modified "project-new.xdk" file.
  • Open the Intel XDK.
  • Goto the Projects tab.
  • Select "Open an Intel XDK Project" (the green button at the bottom left of the Projects tab).
  • To open this new project, locate the new "project-new.xdk" file inside the new project folder you copied above.
  • Don't forget to change the App ID in your new project. This is necessary to avoid conflicts with the project you copied from, in the store and when side-loading onto a device.

My project does not include a www folder. How do I fix it so it includes a www or source directory?

The Intel XDK HTML5 and Cordova project file structures are meant to mimic a standard Cordova project. In a Cordova (or PhoneGap) project there is a subdirectory (or folder) named www that contains all of the HTML5 source code and asset files that make up your application. For best results, it is advised that you follow this convention, of putting your source inside a "source directory" inside of your project folder.

This most commonly happens as the result of exporting a project from an external tool, such as Construct2, or as the result of importing an existing HTML5 web app that you are converting into a hybrid mobile application (eg., an Intel XDK Corodova app). If you would like to convert an existing Intel XDK project into this format, follow the steps below:

  • Exit the Intel XDK.
  • Copy the entire project directory:
    • on Windows, use File Explorer to "right-click" and "copy" your project directory, then "right-click" and "paste"
    • on Mac use Finder to "right-click" and then "duplicate" your project directory
    • on Linux, open a terminal window, "cd" to the folder that contains your project, and type "cp -a old-project/ new-project/" at the terminal prompt (where "old-project/" is the folder name of your existing project that you want to copy and "new-project/" is the name of the new folder that will contain a copy of your existing project)
  • Create a "www" directory inside the new duplicate project you just created above.
  • Move your index.html and other source and asset files to the "www" directory you just created -- this is now your "source" directory, located inside your "project" directory (do not move the <project-name>.xdk and xdke files and any intelxdk.config.*.xml files, those must stay in the root of the project directory)
  • Inside the new project that you made above (by making a copy of the old project), rename the <project-name>.xdk file and <project-name>.xdke files to something like project-copy.xdk and project-copy.xdke (anything you like, just something different than the original project, preferably the same name as the new project folder in which you are making this new project).
  • Using a TEXT EDITOR (only) (such as Notepad or Sublime or Brackets or some other TEXT editor), open the new "project-copy.xdk" file (whatever you named it) and find the line named projectGuid, it will look something like this:
    "projectGuid": "a863c382-ca05-4aa4-8601-375f9f209b67",
  • Change the "GUID" to all zeroes, like this: "00000000-0000-0000-000000000000"
  • A few lines down find: "sourceDirectory": "",
  • Change it to this: "sourceDirectory": "www",
  • Save the modified "project-copy.xdk" file.
  • Open the Intel XDK.
  • Goto the Projects tab.
  • Select "Open an Intel XDK Project" (the green button at the bottom left of the Projects tab).
  • To open this new project, locate the new "project-copy.xdk" file inside the new project folder you copied above.

Can I install more than one copy of the Intel XDK onto my development system?

Yes, you can install more than one version onto your development system. However, you cannot run multiple instances of the Intel XDK at the same time. Be aware that new releases sometimes change the project file format, so it is a good idea, in these cases, to make a copy of your project if you need to experiment with a different version of the Intel XDK. See the instructions in a FAQ entry above regarding how to make a copy of your Intel XDK project.

Follow the instructions in this forum post to install more than one copy of the Intel XDK onto your development system.

On Apple OS X* and Linux* systems, does the Intel XDK need the OpenSSL* library installed?

Yes. Several features of the Intel XDK require the OpenSSL library, which typically comes pre-installed on Linux and OS X systems. If the Intel XDK reports that it could not find libssl, go to https://www.openssl.org to download and install it.

I have a web application that I would like to distribute in app stores without major modifications. Is this possible using the Intel XDK?

Yes, if you have a true web app or “client app” that only uses HTML, CSS and JavaScript, it is usually not too difficult to convert it to a Cordova hybrid application (this is what the Intel XDK builds when you create an HTML5 app). If you rely heavily on PHP or other server scripting languages embedded in your pages you will have more work to do. Because your Cordova app is not associated with a server, you cannot rely on server-based programming techniques; instead, you must rewrite any such code to user RESTful APIs that your app interacts with using, for example, AJAX calls.

What is the best training approach to using the Intel XDK for a newbie?

First, become well-versed in the art of client web apps, apps that rely only on HTML, CSS and JavaScript and utilize RESTful APIs to talk to network services. With that you will have mastered 80% of the problem. After that, it is simply a matter of understanding how Cordova plugins are able to extend the JavaScript API for access to features of the platform. For HTML5 training there are many sites providing tutorials. It may also help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, which will help you understand some of the differences between developing for a traditional server-based environment and developing for the Intel XDK hybrid Cordova app environment.

What is the best platform to start building an app with the Intel XDK? And what are the important differences between the Android, iOS and other mobile platforms?

There is no one most important difference between the Android, iOS and other platforms. It is important to understand that the HTML5 runtime engine that executes your app on each platform will vary as a function of the platform. Just as there are differences between Chrome and Firefox and Safari and Internet Explorer, there are differences between iOS 9 and iOS 8 and Android 4 and Android 5, etc. Android has the most significant differences between vendors and versions of Android. This is one of the reasons the Intel XDK offers the Crosswalk for Android build option, to normalize and update the Android issues.

In general, if you can get your app working well on Android (or Crosswalk for Android) first you will generally have fewer issues to deal with when you start to work on the iOS and Windows platforms. In addition, the Android platform has the most flexible and useful debug options available, so it is the easiest platform to use for debugging and testing your app.

Is my password encrypted and why is it limited to fifteen characters?

Yes, your password is stored encrypted and is managed by https://signin.intel.com. Your Intel XDK userid and password can also be used to log into the Intel XDK forum as well as the Intel Developer Zone. the Intel XDK does not store nor does it manage your userid and password.

The rules regarding allowed userids and passwords are answered on this Sign In FAQ page, where you can also find help on recovering and changing your password.

Why does the Intel XDK take a long time to start on Linux or Mac?

...and why am I getting this error message? "Attempt to contact authentication server is taking a long time. You can wait, or check your network connection and try again."

At startup, the Intel XDK attempts to automatically determine the proxy settings for your machine. Unfortunately, on some system configurations it is unable to reliably detect your system proxy settings. As an example, you might see something like this image when starting the Intel XDK.

On some systems you can get around this problem by setting some proxy environment variables and then starting the Intel XDK from a command-line that includes those configured environment variables. To set those environment variables, similar to the following:

$ export no_proxy="localhost,127.0.0.1/8,::1"
$ export NO_PROXY="localhost,127.0.0.1/8,::1"
$ export http_proxy=http://proxy.mydomain.com:123/
$ export HTTP_PROXY=http://proxy.mydomain.com:123/
$ export https_proxy=http://proxy.mydomain.com:123/
$ export HTTPS_PROXY=http://proxy.mydomain.com:123/

IMPORTANT! The name of your proxy server and the port (or ports) that your proxy server requires will be different than those shown in the example above. Please consult with your IT department to find out what values are appropriate for your site. Intel has no way of knowing what configuration is appropriate for your network.

If you use the Intel XDK in multiple locations (at work and at home), you may have to change the proxy settings before starting the Intel XDK after switching to a new network location. For example, many work networks use a proxy server, but most home networks do not require such a configuration. In that case, you need to be sure to "unset" the proxy environment variables before starting the Intel XDK on a non-proxy network.

After you have successfully configured your proxy environment variables, you can start the Intel XDK manually, from the command-line.

On a Mac, where the Intel XDK is installed in the default location, type the following (from a terminal window that has the above environment variables set):

$ open /Applications/Intel\ XDK.app/

On a Linux machine, assuming the Intel XDK has been installed in the ~/intel/XDK directory, type the following (from a terminal window that has the above environment variables set):

$ ~/intel/XDK/xdk.sh &

In the Linux case, you will need to adjust the directory name that points to the xdk.sh file in order to start. The example above assumes a local install into the ~/intel/XDK directory. Since Linux installations have more options regarding the installation directory, you will need to adjust the above to suit your particular system and install directory.

How do I generate a P12 file on a Windows machine?

See these articles:

How do I change the default dir for creating new projects in the Intel XDK?

You can change the default new project location manually by modifying a field in the global-settings.xdk file. Locate the global-settings.xdk file on your system (the precise location varies as a function of the OS) and find this JSON object inside that file:

"projects-tab": {"defaultPath": "/Users/paul/Documents/XDK","LastSortType": "descending|Name","lastSortType": "descending|Opened","thirdPartyDisclaimerAcked": true
  },

The example above came from a Mac. On a Mac the global-settings.xdk file is located in the "~/Library/Application Support/XDK" directory.

On a Windows machine the global-settings.xdk file is normally found in the "%LocalAppData%\XDK" directory. The part you are looking for will look something like this:

"projects-tab": {"thirdPartyDisclaimerAcked": false,"LastSortType": "descending|Name","lastSortType": "descending|Opened","defaultPath": "C:\\Users\\paul/Documents"
  },

Obviously, it's the defaultPath part you want to change.

BE CAREFUL WHEN YOU EDIT THE GLOBAL-SETTINGS.XDK FILE!! You've been warned...

Make sure the result is proper JSON when you are done, or it may cause your XDK to cough and hack loudly. Make a backup copy of global-settings.xdk before you start, just in case.

Where I can find recent and upcoming webinars list?

How can I change the email address associated with my Intel XDK login?

Login to the Intel Developer Zone with your Intel XDK account userid and password and then locate your "account dashboard." Click the "pencil icon" next to your name to open the "Personal Profile" section of your account, where you can edit your "Name & Contact Info," including the email address associated with your account, under the "Private" section of your profile.

What network addresses must I enable in my firewall to insure the Intel XDK will work on my restricted network?

Normally, access to the external servers that the Intel XDK uses is handled automatically by your proxy server. However, if you are working in an environment that has restricted Internet access and you need to provide your IT department with a list of URLs that you need access to in order to use the Intel XDK, then please provide them with the following list of domain names:

  • appcenter.html5tools-software.intel.com (for communication with the build servers)
  • s3.amazonaws.com (for downloading sample apps and built apps)
  • download.xdk.intel.com (for getting XDK updates)
  • debug-software.intel.com (for using the Test tab weinre debug feature)
  • xdk-feed-proxy.html5tools-software.intel.com (for receiving the tweets in the upper right corner of the XDK)
  • signin.intel.com (for logging into the XDK)
  • sfederation.intel.com (for logging into the XDK)

Normally this should be handled by your network proxy (if you're on a corporate network) or should not be an issue if you are working on a typical home network.

I cannot create a login for the Intel XDK, how do I create a userid and password to use the Intel XDK?

If you have downloaded and installed the Intel XDK but are having trouble creating a login, you can create the login outside the Intel XDK. To do this, go to the Intel Developer Zone and push the "Join Today" button. After you have created your Intel Developer Zone login you can return to the Intel XDK and use that userid and password to login to the Intel XDK. This same userid and password can also be used to login to the Intel XDK forum.

Installing the Intel XDK on Windows fails with a "Package signature verification failed." message.

If you receive a "Package signature verification failed" message (see image below) when installing the Intel XDK on your system, it is likely due to one of the following two reasons:

  • Your system does not have a properly installed "root certificate" file, which is needed to confirm that the install package is good.
  • The install package is corrupt and failed the verification step.

The first case can happen if you are attempting to install the Intel XDK on an unsupported version of Windows. The Intel XDK is only supported on Microsoft Windows 7 and higher. If you attempt to install on Windows Vista (or earlier) you may see this verification error. The workaround is to install the Intel XDK on a Windows 7 or greater machine.

The second case is likely due to a corruption of the install package during download or due to tampering. The workaround is to re-download the install package and attempt another install.

If you are installing on a Windows 7 (or greater) machine and you see this message it is likely due to a missing or bad root certificate on your system. To fix this you may need to start the "Certificate Propagation" service. Open the Windows "services.msc" panel and then start the "Certificate Propagation" service. Additional links related to this problem can be found here > https://technet.microsoft.com/en-us/library/cc754841.aspx

See this forum thread for additional help regarding this issue > https://software.intel.com/en-us/forums/intel-xdk/topic/603992

Troubles installing the Intel XDK on a Linux or Ubuntu system, which option should I choose?

Choose the local user option, not root or sudo, when installing the Intel XDK on your Linux or Ubuntu system. This is the most reliable and trouble-free option and is the default installation option. This will insure that the Intel XDK has all the proper permissions necessary to execute properly on your Linux system. The Intel XDK will be installed in a subdirectory of your home (~) directory.

Inactive account/ login issue/ problem updating an APK in store, How do I request account transfer?

As of June 26, 2015 we migrated all of Intel XDK accounts to the more secure intel.com login system (the same login system you use to access this forum).

We have migrated nearly all active users to the new login system. Unfortunately, there are a few active user accounts that we could not automatically migrate to intel.com, primarily because the intel.com login system does not allow the use of some characters in userids that were allowed in the old login system.

If you have not used the Intel XDK for a long time prior to June 2015, your account may not have been automatically migrated. If you own an "inactive" account it will have to be manually migrated -- please try logging into the Intel XDK with your old userid and password, to determine if it no longer works. If you find that you cannot login to your existing Intel XDK account, and still need access to your old account, please send a message to html5tools@intel.com and include your userid and the email address associated with that userid, so we can guide you through the steps required to reactivate your old account.

Alternatively, you can create a new Intel XDK account. If you have submitted an app to the Android store from your old account you will need access to that old account to retrieve the Android signing certificates in order to upgrade that app on the Android store; in that case, send an email to html5tools@intel.com with your old account username and email and new account information.

Connection Problems? -- Intel XDK SSL certificates update

On January 26, 2016 we updated the SSL certificates on our back-end systems to SHA2 certificates. The existing certificates were due to expire in February of 2016. We have also disabled support for obsolete protocols.

If you are experiencing persistent connection issues (since Jan 26, 2016), please post a problem report on the forum and include in your problem report:

  • the operation that failed
  • the version of your XDK
  • the version of your operating system
  • your geographic region
  • and a screen capture

How do I resolve build failure: "libpng error: Not a PNG file"?  

f you are experiencing build failures with CLI 5 Android builds, and the detailed error log includes a message similar to the following:

Execution failed for task ':mergeArmv7ReleaseResources'.> Error: Failed to run command: /Developer/android-sdk-linux/build-tools/22.0.1/aapt s -i .../platforms/android/res/drawable-land-hdpi/screen.png -o .../platforms/android/build/intermediates/res/armv7/release/drawable-land-hdpi-v4/screen.png

Error Code: 42

Output: libpng error: Not a PNG file

You need to change the format of your icon and/or splash screen images to PNG format.

The error message refers to a file named "screen.png" -- which is what each of your splash screens were renamed to before they were moved into the build project resource directories. Unfortunately, JPG images were supplied for use as splash screen images, not PNG images. So the files were renamed and found by the build system to be invalid.

Convert your splash screen images to PNG format. Renaming JPG images to PNG will not work! You must convert your JPG images into PNG format images using an appropriate image editing tool. The Intel XDK does not provide any such conversion tool.

Beginning with Cordova CLI 5, all icons and splash screen images must be supplied in PNG format. This applies to all supported platforms. This is an undocumented "new feature" of the Cordova CLI 5 build system that was implemented by the Apache Cordova project.

Why do I get a "Parse Error" when I try to install my built APK on my Android device?

Because you have built an "unsigned" Android APK. You must click the "signed" box in the Android Build Settings section of the Projects tab if you want to install an APK on your device. The only reason you would choose to create an "unsigned" APK is if you need to sign it manually. This is very rare and not the normal situation.

My converted legacy keystore does not work. Google Play is rejecting my updated app.

The keystore you converted when you updated to 3088 (now 3240 or later) is the same keystore you were using in 2893. When you upgraded to 3088 (or later) and "converted" your legacy keystore, you re-signed and renamed your legacy keystore and it was transferred into a database to be used with the Intel XDK certificate management tool. It is still the same keystore, but with an alias name and password assigned by you and accessible directly by you through the Intel XDK.

If you kept the converted legacy keystore in your account following the conversion you can download that keystore from the Intel XDK for safe keeping (do not delete it from your account or from your system). Make sure you keep track of the new password(s) you assigned to the converted keystore.

There are two problems we have experienced with converted legacy keystores at the time of the 3088 release (April, 2016):

  • Using foreign (non-ASCII) characters in the new alias name and passwords were being corrupted.
  • Final signing of your APK by the build system was being done with RSA256 rather than SHA1.

Both of the above items have been resolved and should no longer be an issue.

If you are currently unable to complete a build with your converted legacy keystore (i.e., builds fail when you use the converted legacy keystore but they succeed when you use a new keystore) the first bullet above is likely the reason your converted keystore is not working. In that case we can reset your converted keystore and give you the option to convert it again. You do this by requesting that your legacy keystore be "reset" by filling out this form. For 100% surety during that second conversion, use only 7-bit ASCII characters in the alias name you assign and for the password(s) you assign.

IMPORTANT: using the legacy certificate to build your Android app is ONLY necessary if you have already published an app to an Android store and need to update that app. If you have never published an app to an Android store using the legacy certificate you do not need to concern yourself with resetting and reconverting your legacy keystore. It is easier, in that case, to create a new Android keystore and use that new keystore.

If you ARE able to successfully build your app with the converted legacy keystore, but your updated app (in the Google store) does not install on some older Android 4.x devices (typically a subset of Android 4.0-4.2 devices), the second bullet cited above is likely the reason for the problem. The solution, in that case, is to rebuild your app and resubmit it to the store (that problem was a build-system problem that has been resolved).

How can I have others beta test my app using Intel App Preview?

Apps that you sync to your Intel XDK account, using the Test tab's green "Push Files" button, can only be accessed by logging into Intel App Preview with the same Intel XDK account credentials that you used to push the files to the cloud. In other words, you can only download and run your app for testing with Intel App Preview if you log into the same account that you used to upload that test app. This restriction applies to downloading your app into Intel App Preview via the "Server Apps" tab, at the bottom of the Intel App Preview screen, or by scanning the QR code displayed on the Intel XDK Test tab using the camera icon in the upper right corner of Intel App Preview.

If you want to allow others to test your app, using Intel App Preview, it means you must use one of two options:

  • give them your Intel XDK userid and password
  • create an Intel XDK "test account" and provide your testers with that userid and password

For security sake, we highly recommend you use the second option (create an Intel XDK "test account"). 

A "test account" is simply a second Intel XDK account that you do not plan to use for development or builds. Do not use the same email address for your "test account" as you are using for your main development account. You should use a "throw away" email address for that "test account" (an email address that you do not care about).

Assuming you have created an Intel XDK "test account" and have instructed your testers to download and install Intel App Preview; have provided them with your "test account" userid and password; and you are ready to have them test:

  • sign out of your Intel XDK "development account" (using the little "man" icon in the upper right)
  • sign into your "test account" (again, using the little "man" icon in the Intel XDK toolbar)
  • make sure you have selected the project that you want users to test, on the Projects tab
  • goto the Test tab
  • make sure "MOBILE" is selected (upper left of the Test tab)
  • push the green "PUSH FILES" button on the Test tab
  • log out of your "test account"
  • log into your development account

Then, tell your beta testers to log into Intel App Preview with your "test account" credentials and instruct them to choose the "Server Apps" tab at the bottom of the Intel App Preview screen. From there they should see the name of the app you synced using the Test tab and can simply start it by touching the app name (followed by the big blue and white "Launch This App" button). Staring the app this way is actually easier than sending them a copy of the QR code. The QR code is very dense and is hard to read with some devices, dependent on the quality of the camera in their device.

Note that when running your test app inside of Intel App Preview they cannot test any features associated with third-party plugins, only core Cordova plugins. Thus, you need to insure that those parts of your apps that depend on non-core Cordova plugins have been disabled or have exception handlers to prevent your app from either crashing or freezing.

I'm having trouble making Google Maps work with my Intel XDK app. What can I do?

There are many reasons that can cause your attempt to use Google Maps to fail. Mostly it is due to the fact that you need to download the Google Maps API (JavaScript library) at runtime to make things work. However, there is no guarantee that you will have a good network connection, so if you do it the way you are used to doing it, in a browser...

<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=true"></script>

...you may get yourself into trouble, in an Intel XDK Cordova app. See Loading Google Maps in Cordova the Right Way for an excellent tutorial on why this is a problem and how to deal with it. Also, it may help to read Five Useful Tips on Getting Started Building Cordova Mobile Apps with the Intel XDK, especially item #3, to get a better understanding of why you shouldn't use the "browser technique" you're familiar with.

An alternative is to use a mapping tool that allows you to include the JavaScript directly in your app, rather than downloading it over the network each time your app starts. Several Intel XDK developers have reported very good luck with the open-source JavaScript library named LeafletJS that uses OpenStreet as it's map database source.

You can also search the Cordova Plugin Database for Cordova plugins that implement mapping features, in some cases using native SDKs and libraries.

How do I fix "Cannot find the Intel XDK. Make sure your device and intel XDK are on the same wireless network." error messages?

You can either disable your firewall or allow access through the firewall for the Intel XDK. To allow access through the Windows firewall goto the Windows Control Panel and search for the Firewall (Control Panel > System and Security > Windows Firewall > Allowed Apps) and enable Node Webkit (nw or nw.exe) through the firewall

See the image below (this image is from a Windows 8.1 system).

Google Services needs my SHA1 fingerprint. Where do I get my app's SHA fingerprint?

Your app's SHA fingerprint is part of your build signing certificate. Specifically, it is part of the signing certificate that you used to build your app. The Intel XDK provides a way to download your build certificates directly from within the Intel XDK application (see the Intel XDK documentation for details on how to manage your build certificates). Once you have downloaded your build certificate you can use these instructions provided by Google, to extract the fingerprint, or simply search the Internet for "extract fingerprint from android build certificate" to find many articles detailing this process.

Why am I unable to test or build or connect to the old build server with Intel XDK version 2893?

This is an Important Note Regarding the use of Intel XDK Versions 2893 and Older!!

As of June 13, 2016, versions of the Intel XDK released prior to March 2016 (2893 and older) can no longer use the Build tab, the Test tab or Intel App Preview; and can no longer create custom debug modules for use with the Debug and Profile tabs. This change was necessary to improve the security and performance of our Intel XDK cloud-based build system. If you are using version 2893 or older, of the Intel XDK, you must upgrade to version 3088 or greater to continue to develop, debug and build Intel XDK Cordova apps.

The error message you see below, "NOTICE: Internet Connection and Login Required," when trying to use the Build tab is due to the fact that the cloud-based component that was used by those older versions of the Intel XDK work has been retired and is no longer present. The error message appears to be misleading, but is the easiest way to identify this condition. 

How do I run the Intel XDK on Fedora Linux?

See the instructions below, copied from this forum post:

$ sudo find xdk/install/dir -name libudev.so.0
$ cd dir/found/above
$ sudo rm libudev.so.0
$ sudo ln -s /lib64/libudev.so.1 libudev.so.0

Note the "xdk/install/dir" is the name of the directory where you installed the Intel XDK. This might be "/opt/intel/xdk" or "~/intel/xdk" or something similar. Since the Linux install is flexible regarding the precise installation location you may have to search to find it on your system.

Once you find that libudev.so file in the Intel XDK install directory you must "cd" to that directory to finish the operations as written above.

Additional instructions have been provided in the related forum thread; please see that thread for the latest information regarding hints on how to make the Intel XDK run on a Fedora Linux system.

Back to FAQs Main

Crowdfunding Home Security - The Story of Orbii (So Far)

$
0
0

When Orbii Co-Founder Omar Barlas was shopping for a camera to set up in his home two years ago, he didn’t know it would lead to a brand-new business venture. But when he wasn’t able to find what he was looking for—a single device that was drivable from room to room—he decided to make it himself, a decision which, so far, has led to a showcase at 2016’s Consumer Electronics Show and an Indiegogo campaign that was fully-funded within the first week.

We sat down with him to discuss Orbii’s success, as well as what they learned through the process, including what they would or wouldn’t do next time around.

Orbii’s Story

In the simple time-honored tradition of invention, Orbii came to be because there was a need unfulfilled—Barlas wanted a single camera for home security purposes that he could drive from room to room, but all of the available options required multiple camera setups for full coverage. Barlas moved quickly into prototyping, intent upon creating a working model as soon as possible—something that could not only prove the concept and define future iterations, but something that could also give reviewers and potential customers a chance to experience the idea firsthand.

The first prototype was showcased at CES 2016, and received great response. This confirmed Orbii’s initial market research findings, and it also gave them the opportunity to talk to more potential consumers. Additional market research was done through Orbii’s website, where potential consumers were able to sign-up and offer their insights. One key learning was that there was an active secondary market of pet owners who were interested in the product as a way to monitor their pets when they weren’t at home—using Orbii’s microphone and speaker to interact with them from afar. While this didn’t change the overall focus of the product, it allowed the product developers to keep all of their customers in mind when considering new features, and encouraged them to think about additional creative opportunities in marketing.

Further prototyping and market validation led the way to the launch of the Indiegogo campaign in May 2016. In order to fund the development of the product, Orbii needed pre-sales. In order to encourage pre-sales, they offered a variety of incentives for potential buyers—essentially providing deep discounts to customers who were willing to order early and support product development.

As a result of their success on Indiegogo, the company will continue to develop the product, while also continuing to explore distribution and partnership opportunities. The first round of products is expected to launch in April 2017.

Understanding Their Audience

Orbii’s primary audience is Homeowners and Business Owners, but they are also serving a number of secondary markets, including:

  • Parents
  • Children of Elderly Parents
  • Pet Owners
  • Real Estate Inspectors
  • Building Contractors
  • Aged Care Services
  • First Responders
  • Military

This audience was defined through early market research and a survey. Orbii’s primary method of research was in simple face-to-face communications: They talked to people. At a variety of small tech events, at CES, at New York Tech Day 2016, they demonstrated the prototype and asked people what they thought about it, how they might use it—what promise it provided them.

This phase of market research also gave them an opportunity to pivot. The core functionality, features, and market remained the same, but based on early feedback they made some changes to the internal design of the product.
 

Crowdfunding: How and Why?

Orbii chose crowdfunding for two reasons—to fund mainstream product development, and to conduct market research. Because this method involves presenting your idea and selling your future product to actual consumers, it gives you access to additional market research, and a group of dedicated consumers who are willing to support you both in terms of finances and in terms of product feedback and requests.
 

Crowdfunding? How Does it Work?

Dedicated manager. First things first—consider hiring a full-time person to manage your crowdfunding campaign. It’s not enough to just put something up and see what happens, and chances are good that the core team will need to continue working on product development at the same time. This person will need to prepare weekly updates, and to respond to consumer questions in a timely manner, while allowing for ongoing simultaneous development. Responding to consumers is really key, both in terms of engaging with that consumer, and for the benefit of future potential customers. “If you don’t respond, then you’ll stop getting backers coming back to your site. That’s what people see,” said Barlas.

Creation of assets. Consumers need to see the product in action, and the best way to do that is through professional videos and lifestyle photos of the product in action. Orbii hired an outside marketing firm to do this work for them, knowing that their talents were better left focused on product and business development, while they left the marketing to the pros. It’s also a good idea to provide videos of product testing and use cases—these may be less polished than the other assets, but they help legitimize your claims, and they also involve consumers in the process, providing them with a sense of ownership as well as excitement bout the final product to come.

Incentives. Consumers need a reason to pre-order, especially when a company is new and untested. There are a variety of ways to approach this, but the key thing is to give them something beyond what they’d be able to buy in a store. Orbii deeply discounted the product for early backers, allowing them to not only get the product first, but to get it for a significantly-reduced price.

Results! Orbii’s crowdfunding campaign was highly successful. After meeting 100% of their initial goal of $6,000 by the end of the first week, they went on to raise a total of $35,000 in the first month, from more than 260 backers. There are hurdles to crowdfunding while development is still in process, but in this case it paid off, allowing Orbii to continue to fund development, and letting customers get in on the ground floor.
 

What Would Orbii Have Done Differently?

Despite Orbii’s success, there are always things to learn and things that could be approached differently the next time around. Barlas told us there were three key things that in retrospect they should have done more aggressively before launching the campaign:

1.Collection of sign-ups from interested customers early on.
During all of those great conversations at tech events, while they were conducting market research and demonstrating the prototype, they could have done more to collect sign-ups from interested consumers. With more effort, a really great contact list could’ve been created.

2.Collection of more social media/facebook followers early on.
Similarly, more efforts could’ve been made online to capture and collect sign-ups from those who’d expressed an interest in the product.

3.Align press/media contacts to write about Orbii on the day of launch.
Timing is key. Orbii had a lot of good press at CES in January, but the campaign didn’t launch until May. Because of this, they weren’t able to maximize their exposure. If they’d coordinated their efforts and had interested reviewers and tech press lined up to write about the product in May, they would have had a larger audience for their Indiegogo campaign, and even more success.
 

Marketing

What did Orbii do to get the word out? For a crowdfunding campaign to be a success, it’s important to share your story and your product idea with as many people as possible. Orbii’s primary approach, as we’ve discussed, was to attend tech events and talk to people one-on-one. This gave them a venue to demonstrate the prototypes, but it was also a natural way to let people know about the upcoming campaign. Additionally, Orbii hired an agency to help conduct a Facebook campaign, which brought in new product backers. 
 

Pricing

Orbii needed to not only determine pricing for its product, they also needed to figure out pricing for incentives. “Whenever you’re thinking about crowdfunding, you’ve got to offer some special deal to the backers, otherwise no one would be interested in ordering in advance,” says Barlas. In Orbii’s case, they went with a price discount model. The campaign kicked off with pricing at 60% off of the retail price. The next week, they offered 50% off, then 40% off the following week. This allowed interested customers to buy in early, and to save in the process. Increasing the price each week, and publicizing those upcoming price increases helped drive excitement and encourage people to buy while the price was still low.

Pricing for the product itself was a more straightforward task. They looked at the market to see how other products were priced, and based on their extensive prototyping and pre-orders, they determined the estimated cost of the Bill of Materials, and the retail price was calculated from that BOM.  
 

Keys to Success

1.Be consistent and aggressive with product development.
Despite hurdles, continue working toward the product that you’ve envisioned, building prototypes and revising along the way. Even when Orbii’s team had to use personal funds and other revenue streams to fund development, they kept going.

2.Build an MVP quickly.
You need a functional prototype that performs the way it is supposed to perform, so move quickly to this stage of development, and create your MVP, or Minimum Viable Product. Consumers will know if it’s real or not, and press will need to evaluate the prototype in order to write about it.

3.Hire good marketers.
Know where your talents lie and hire help for the things outside your expertise (when you can). Orbii’s team is made of developers and visionaries, so they looked outside for marketing, and were able to remain focused on product and business development.  
 

Future Plans

Now that Orbii has been funded, what happens next? Orbii's team remains focused on production and the consumer product launch next year. At the same time, they’re working to build relationships with distributors, and looking for potential partners, such as a Cloud Services Provider. They are also continuing to raise investment for faster production, building on the success of their crowdfunding campaign.

OpenGL* Performance Tips: Use Native Formats for Best Rendering Performance

$
0
0

Download[PDF 703KB]

Download Code Sample from Github

Introduction

Game developers often use OpenGL to handle the rendering chores for graphics-intensive games. OpenGL is an application programming interface for efficiently rendering two- and three-dimensional vector graphics. It is available on most platforms.

This article demonstrates how using the proper texture format can improve OpenGL performance—in particular, using native texture formats will give game developers the best OpenGL performance. Accompanying the article is a C++ example application that shows the effects on rendering performance when using a variety of texture formats. Note that while this article refers to concepts relevant to graphical game developers, these concepts apply to all applications that use OpenGL 4.3 and higher. The sample code is written in C++ and is designed for Windows* 8.1 and 10 devices.

Requirements

The following are required to build and run the example application:

  • A computer with a 6th generation Intel® Core™ processor (code-named Skylake)
  • OpenGL 4.3 or higher
  • Microsoft Visual Studio 2013 or newer

Skylake Processor Graphics

The 6th generation Intel Core processors, also known as Skylake, provide superior two- and three-dimensional graphics performance, reaching up to 1152 GFLOPS. Its multicore architecture improves performance and increases the number of instructions per clock cycle.

The 6th gen Intel Core processors offer a number of new benefits over previous generations and provide significant boosts to overall computing horsepower and visual performance. Sample enhancements include a GPU that, coupled with the CPU's added computing muscle, provides up to 40 percent better graphics performance over prior Intel® Processor Graphics. The 6th gen Intel Core processors have been redesigned to offer higher-fidelity visual output, higher-resolution video playback, and more seamless responsiveness for systems with lower power usage. With support for 4K video playback and extended overclocking, Skylake is ideal for game developers. 

GPU memory access includes atomic min, max, and compare-and-exchange for 32-bit floating point values in either shared local memory or global memory. The new architecture also offers a performance improvement for back-to-back atomics to the same address. Tiled resources include support for large, partially resident (sparse) textures and buffers. Reading unmapped tiles returns zero, and writes to them are discarded. There are also new shader instructions for clamping LOD and obtaining operation status. There is now support for larger texture and buffer sizes. (For example, you can use up to 128k x 128k x 8B mipmapped 2D textures.)

Bindless resources increase the number of dynamic resources a shader may use, from about 256 to 2,000,000 when supported by the graphics API. This change reduces the overhead associated with updating binding tables and provides more flexibility to programmers.

Execution units have improved native 16-bit floating point support as well. This enhanced floating point support leads to both power and performance benefits when using half precision.

Display features further offer multiplane overlay options with hardware support to scale, convert, color correct, and composite multiple surfaces at display time. Surfaces can additionally come from separate swap chains using different update frequencies and resolutions (for example, full-resolution GUI elements composited on top of up-scaled, lower-resolution frame renders) to provide significant enhancements.

Its architecture supports GPUs with up to three slices (providing 72 EUs). This architecture also offers increased power gating and clock domain flexibility, which are well worth taking advantage of.

Lesson 2: Use Native Texture Formats for Best Rendering Performance

Anyone who works with OpenGL is familiar with working with textures. However, not all textures are created equal—some texture formats have better rendering performance than other formats. Using formats that are native to the hardware means that the texture can be used “as is,” avoiding an unnecessary conversion.

This lesson shows the impact of different formats—the example cycles through a variety of different texture formats as it renders an image in a window. For each format the current performance is displayed in milliseconds-per-frame, along with the number of frames-per-second. Pressing the spacebar rotates to the next texture in the list so you can see which formats work best on your hardware.

The example uses the following formats. This list is based on the list of OpenGL “Required Formats” at https://www.opengl.org/wiki/Image_Format:

  • GL_RGBA8
  • GL_RGBA16
  • GL_RGBA16F
  • GL_RGBA32F
  • GL_RGBA8I
  • GL_RGBA16I
  • GL_RGBA32I
  • GL_RGBA8UI
  • GL_RGBA16UI
  • GL_RGBA32UI
  • GL_RGB10_A2
  • GL_RGB10_A2UI
  • GL_R11F_G11F_B10F
  • GL_SRGB8_ALPHA8
  • GL_RGB8
  • GL_RGB16
  • GL_RGBA8_SNORM
  • GL_RGBA16_SNORM
  • GL_RGB8_SNORM
  • GL_RGB16_SNORM
  • GL_RGB16F
  • GL_RGB32F
  • GL_RGB8I
  • GL_RGB16I
  • GL_RGB32I
  • GL_RGB8UI
  • GL_RGB16UI
  • GL_RGB32UI
  • GL_SRGB8
  • GL_SGB9_ES

Building and Running the Application

Follow these steps to compile and run the example application.

  1. Download the ZIP file containing the source code for the example application, and then unpack it into a working directory.
  2. Open the lesson2a_textureformat/lesson2a.sln file in Microsoft Visual Studio 2013.
  3. Select <Build>/<Build Solution> to build the application.
  4. Upon successful build you can run the example from within Visual Studio.

Once the application is running, a main window opens and you will see an image. The Microsoft Visual Studio 2013 console window displays the type of texture used to render the image and its performance measurements. Press the spacebar to change to the next texture format. Press ESC to exit the application.

Code Highlights

The code for this example is straightforward, but there are a few items to highlight.

First, we are going to need three different fragment shaders, based upon the texture being used. One shader will get its output color from a normalized texture, another is designed for non-normalized, signed integer textures, and the last is for non-normalized, unsigned integer textures.

// Fragment shader gets output color from a normalized texture
static std::string fragmentShader ="#version 430 core\n""\n""uniform sampler2D texUnit;\n""\n""smooth in vec2 texcoord;\n""\n""layout(location = 0) out vec4 fragColor;\n""\n""void main()\n""{\n""    fragColor = texture(texUnit, texcoord);\n""}\n"
;

// Fragment shader gets output color from a non-normalized signed integer texture
static std::string ifragmentShader =
    "#version 430 core\n""\n""uniform isampler2D texUnit;\n""\n""smooth in vec2 texcoord;\n""\n""layout(location = 0) out vec4 fragColor;\n""\n""void main()\n""{\n""    fragColor = vec4(texture(texUnit, texcoord))/255.0;\n""}\n"
;

// Fragment shader gets output color from a non-normalized unsigned integer texture
static std::string ufragmentShader =
    "#version 430 core\n""\n""uniform usampler2D texUnit;\n""\n""smooth in vec2 texcoord;\n""\n""layout(location = 0) out vec4 fragColor;\n""\n""void main()\n""{\n""    fragColor = vec4(texture(texUnit, texcoord))/255.0;\n""}\n"
;

These shaders are compiled and prepared.

    // compile and link the shaders into a program, make it active
    vShader  = compileShader(vertexShader, GL_VERTEX_SHADER);
    fShader  = compileShader(fragmentShader, GL_FRAGMENT_SHADER);
    ifShader = compileShader(ifragmentShader, GL_FRAGMENT_SHADER);
    ufShader = compileShader(ufragmentShader, GL_FRAGMENT_SHADER);
    program  = createProgram({ vShader, fShader });
    iprogram = createProgram({ vShader, ifShader });
    uprogram = createProgram({ vShader, ufShader });

The collection of textures is stored in an array that contains the texture and which program to use.

// Array of structures, one item for each option we're testing
#define F(x,y,z) x, y, #x, 0, z
static struct {
    GLint fmt, type;
    const char* str;
    GLuint obj, &pgm;
} textures[] = {
    F(GL_RGBA8,          GL_RGBA,         program),
    F(GL_RGBA16,         GL_RGBA,         program),
    F(GL_RGBA8_SNORM,    GL_RGBA,         program),
    F(GL_RGBA16_SNORM,   GL_RGBA,         program),
    F(GL_RGBA16F,        GL_RGBA,         program),
    F(GL_RGBA32F,        GL_RGBA,         program),
    F(GL_RGBA8I,         GL_RGBA_INTEGER, iprogram),
    F(GL_RGBA16I,        GL_RGBA_INTEGER, iprogram),
    F(GL_RGBA32I,        GL_RGBA_INTEGER, iprogram),
    F(GL_RGBA8UI,        GL_RGBA_INTEGER, uprogram),
    F(GL_RGBA16UI,       GL_RGBA_INTEGER, uprogram),
    F(GL_RGBA32UI,       GL_RGBA_INTEGER, uprogram),
    F(GL_RGB10_A2,       GL_RGBA,         program),
    F(GL_RGB10_A2UI,     GL_RGBA_INTEGER, uprogram),
    F(GL_R11F_G11F_B10F, GL_RGBA,         program),
    F(GL_SRGB8_ALPHA8,   GL_RGBA,         program),
    F(GL_RGB8,           GL_RGBA,         program),
    F(GL_RGB16,          GL_RGBA,         program),
    F(GL_RGB8_SNORM,     GL_RGBA,         program),
    F(GL_RGB16_SNORM,    GL_RGBA,         program),
    F(GL_RGB16F,         GL_RGBA,         program),
    F(GL_RGB32F,         GL_RGBA,         program),
    F(GL_RGB8I,          GL_RGBA_INTEGER, iprogram),
    F(GL_RGB16I,         GL_RGBA_INTEGER, iprogram),
    F(GL_RGB32I,         GL_RGBA_INTEGER, iprogram),
    F(GL_RGB8UI,         GL_RGBA_INTEGER, uprogram),
    F(GL_RGB16UI,        GL_RGBA_INTEGER, uprogram),
    F(GL_RGB32UI,        GL_RGBA_INTEGER, uprogram),
    F(GL_SRGB8,          GL_RGBA,         program),
};

When it is time to draw the image, the correct texture and format is used based upon the texture array.

// GLUT display function.   Draw one frame's worth of imagery.
void display()
{
    // attribute-less rendering
    glUseProgram(textures[selector].pgm);                                         GLCHK;
    glClear(GL_COLOR_BUFFER_BIT);                                                 GLCHK;
    glBindTexture(GL_TEXTURE_2D, textures[selector].obj);                         GLCHK;
    if (animating) {
        glUniform1f(offset, animation);                                           GLCHK;
    }
    else if (selector) {
        glUniform1f(offset, 0.f);                                                 GLCHK;
    }
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);                                        GLCHK;
    glutSwapBuffers();
}

Each time a video frame is drawn the performance output is updated in the console and the application checks whether the spacebar or ESC is pressed. Pressing the space bar causes the application to move to the next texture in the array; pressing ESC exits the application. When a new texture is loaded the performance measurements are reset and the image animates as a visual indicator that something changed. If no key was pressed the next frame is rendered.

// GLUT idle function.  Called once per video frame.
// Calculate and print timing reports and handle console input.
void idle()
{
    // Calculate performance
    static unsigned __int64 skip;  if (++skip < 512) return;
    static unsigned __int64 start; if (!start &&
         !QueryPerformanceCounter((PLARGE_INTEGER)&start))               __debugbreak();
    unsigned __int64 now;  if (!QueryPerformanceCounter((PLARGE_INTEGER)&now))
                                                                         __debugbreak();
    unsigned __int64 us = elapsedUS(now, start), sec = us / 1000000;
    static unsigned __int64 animationStart;
    static unsigned __int64 cnt; ++cnt;

    // We're either animating
    if (animating)
    {
        float sec = elapsedUS(now, animationStart) / 1000000.f; if (sec < 1.f) {
            animation = (sec < 0.5f ? sec : 1.f - sec) / 0.5f;
        } else {
            animating = false;
            selector = (selector + 1) % _countof(textures); skip = 0;
            print();
        }
    }

    // Or measuring
    else if (sec >= 2)
    {
        printf("frames rendered = %I64u, uS = %I64u, fps = %f,
               milliseconds-per-frame = %f\n", cnt, us, cnt * 1000000. / us,
               us / (cnt * 1000.));
        if (advance) {
            animating = true; animationStart = now;  advance = false;
        } else {
            cnt = start = 0;
        }
    }

    // Get input from the console too.
    HANDLE h = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD r[128]; DWORD n;
    if (PeekConsoleInput(h, r, 128, &n) && n)
        if (ReadConsoleInput(h, r, n, &n))
            for (DWORD i = 0; i < n; ++i)
                if (r[i].EventType == KEY_EVENT && r[i].Event.KeyEvent.bKeyDown)
                    keyboard(r[i].Event.KeyEvent.uChar.AsciiChar, 0, 0);

    // Ask for another frame
    glutPostRedisplay();
}

Conclusion

This example demonstrated that using a texture format native to the GPU will increase performance. This simple application will help you determine the right texture for your Skylake hardware.

By combining this technique with the advantages of the 6th gen Intel Core processors graphic game developers can ensure their games perform the way they were designed.

Download Code Sample

Below is the link to the code samples on Github

https://github.com/IntelSoftware/OpenGLBestPracticesfor6thGenIntelProcessor

References

An Overview of the 6th generation Intel® Core™ processor (code-named Skylake)

Graphics API Developer’s Guide for 6th Generation Intel® Core™ Processors

About the Author

Praveen Kundurthy works in the Intel® Software and Services Group. He has a master’s degree in Computer Engineering. His main interests are mobile technologies, Microsoft Windows*, and game development.

Notes

1 March, Meghana R., “An Overview of the 6th generation Intel® Core™ processor (code-name Skylake).” March 23, 2016. https://software.intel.com/en-us/articles/an-overview-of-the-6th-generation-intel-core-processor-code-named-skylake

Viewing all 3384 articles
Browse latest View live