Matias Kangasjärvelä. Vulkanin Perusteet. Insinööri (AMK), tietotekniikka
|
|
- Otto Timo-Pekka Mäki
- 8 vuotta sitten
- Katselukertoja:
Transkriptio
1 Matias Kangasjärvelä Vulkanin Perusteet Insinööri (AMK), tietotekniikka Kevät 2017
2 TIIVISTELMÄ Tekijä: Matias Kangasjärvelä Työn nimi: Vulkanin perusteet Tutkintonimike: Insinööri (AMK), tietotekniikka Asiasanat: Vulkan, 3D Grafiikka, C++, Grafiikkarajapinta Opinnäytetyön tavoitteena oli luoda käyttöohje Vulkanin perusteisiin ja eroihin muihin grafiikkarajapintoihin verrattuna. Käyttöohjeen seuraaminen vaatii Windows-käyttöjärjestelmän sekä Visual Studio 2015 tai uudemman kehitysympäristön. Lisäksi Vulkanin käyttäminen vaatii tuen näytönohjaimen ajureilta ja Vulkan ohjelmistokehityspaketin. Grafiikkarajapinnalla tarkoitetaan ohjelmointirajapintaa, joka mahdollistaa 3D-grafiikan tuottamisen näytönohjaimella. Vulkan on niin sanottu moderni grafiikkarajapinta, joka mahdollistaa paremmin näytönohjaimien resurssien optimaalista hyödyntämistä. Ensimmäinen osa työstä käy läpi grafiikkarajapintoja yleisesti. Toinen osa syventyy Vulkaniin yleisellä tasolla ja käy läpi sen historiaa ja eroja muihin grafiikkarajapintoihin. Lopuksi kolmannessa osassa työtä käydään läpi yksinkertaisen Vulkan ohjelman avulla Vulkanin perusteita.
3 ABSTRACT Author: Matias Kangasjärvelä Title of the Publication: Basics of Vulkan Degree Title: Bachelor of Engineering Keywords: Vulkan, 3D Rendering, C++, Graphics API The aim of the thesis was to create a guide into the basics of Vulkan and compare it to other graphics APIs (application programming interface). Graphics API is an application programming interface that makes it possible to produce 3D-graphics with the graphics card. Vulkan is a so called modern graphics API that enables the program to make more optimal use of the resources available in the graphics card. Following the guide requires use of the Windows operating system and the Visual Studio 2015 or newer integrated development environment. In addition to this the use of Vulkan requires support from the driver of the graphics card and the Vulkan software development kit. First part of the thesis goes over the different graphics APIs on a general level. The second part focuses on Vulkan on a general level and goes through the history Vulkan and differences compared to other graphics APIs. Lastly the third part goes over the basics of Vulkan using a simple Vulkan program. The final result of this thesis was a look into the basics of Vulkan and some concepts of 3Dgraphics. The tutorial could be used by any C++ programmer trying to create applications with Vulkan.
4 SISÄLLYS 1 JOHDANTO GRAFIIKKARAJAPINTA Historia OpenGL Direct3D Mantle Näytönohjain Yleiset ominaisuudet Laiteläheisyys VULKAN Historia Erot muihin grafiikkarajapintoihin Vulkanin sopivuus Monisäikeistys VULKANIN KÄYTTÄMINEN Instanssi Instanssin luominen Validointi ja virheenkorjaus Laiteobjekti Fyysisen laitteen valinta Jonoperheet Laiteobjektin luominen Komentojonokahva Kuvan esittäminen Ikkunan pinta Vaihtoketju Kuvanäkymä Grafiikkaliukuhihna Varjostimet Piirtokierrokset... 22
5 Kuvapuskurit Grafiikkaliukuhihnan tila Grafiikkaliukuhihnan luominen Komennot Komentopooli Komentopuskurit Datan siirtäminen näytönohjaimelle Verteksipuskurit Indeksipuskurit Kuvan piirtäminen Semaforit Komentopuskurin täyttäminen Kuvan esittäminen YHTEENVETO LÄHTEET LIITTEET... 43
6 TERMILUETTELO AMD DICE GLFW GLSL Khronos Group LunarG Verteksi SPIR-V Advanced Micro Devices, Inc. Yksi suurimpia näytönohjaimien ja prosessoreiden valmistajia. Digital Illusions CE AB. Ruotsalainen mm. Battlefield ja Mirror s Edge pelisarjoista tunnettu pelistudio. Ohjelmointikirjasto, joka mahdollistaa mm. ikkunoiden luomisen ja käyttäjän syötteen hallitsemisen käyttöjärjestelmä riippumattomasti. OpenGL Shading Language. Näytönohjaimen varjostimien kirjoittamiseen käytetty ohjelmointikieli. Vulkania ja OpenGL kehittävä konsortio. Vulkanin ohjelmistokehityspaketin kehityksestä ja levityksestä vastaava yritys. 3D-grafiikassa käytettyjen kolmioiden kärkipiste. Standard Portable Intermediate Representation versio V. Vulkanin käyttämä näytönohjaimen varjostimien välikieli, johon toisessa kielessä kirjoitettu varjostin tulee kääntää.
7 1 1 JOHDANTO 3D-grafiikan käytön yleistyessä 90-luvun alkupuolella alkoivat yleistyä myös näytönohjaimet, jotka mahdollistavat 3D-grafiikan piirtämisen. Monet näistä näytönohjaimista toimivat eri tavoin ja ohjelmien tuli lisätä tuki näytönohjaimille yksitellen. Tähän ongelmaan ratkaisuksi kehitettiin ohjelmointirajapintoja, jotka tunnetaan myös grafiikkarajapintoina, kuten OpenGL ja Direct3D, jotka mahdollistavat 3Dgrafiikan piirtämisen riippumatta siitä, mikä näytönohjain on käytössä [1] [2]. Nykypäivän pelimoottorit vaativat aina suurempia ja suurempia resursseja näytönohjaimilta ja pelinkehittäjät havaitsivat, että vanhat ohjelmointirajapinnat tekevät niiden resurssien hyödyntämisestä hankalaa. Tämä johti uusien, niin sanottujen modernien grafiikkarajapintojen kehittämiseen, joihin myös Vulkan kuuluu. Modernit grafiikkarajapinnat mahdollistavat paremmin tietokoneen kaikkien resurssien hyödyntämisen 3D-grafiikka piirtäessä [3]. Tämän opinnäytetyön tavoitteena on selvittää, mitä moderni grafiikkarajapinta tarkoittaa ja tutustua Vulkanin perusteisiin 3D-grafiikan piirtämisessä. Henkilökohtaisena tavoitteena on oppia Vulkanin käyttäminen.
8 2 2 GRAFIIKKARAJAPINTA Grafiikkarajapinta on näytönohjaimen laiteajurista löytyvä ohjelmointirajapinta, joka tarjoaa abstraktion näytönohjaimen 3D-grafiikan piirtämiseen tarkoitettuihin ominaisuuksiin. Grafiikkarajapintoja käytetään erityisesti pelimoottoreissa 3D-grafiikan reaaliaikaiseen tuottamiseen. 2.1 Historia Grafiikkarajapintoja on historian varrella ollut useita, ja niistä ensimmäiset olivat valmistaja- tai laiteriippuvaisia. 3D-grafiikan yleistyessä myös laiteriippumattomat rajapinnat, joilla voidaan tehdä ohjelmia, jotka toimivat useilla eri alustoilla, yleistyivät OpenGL OpenGL on alun perin Silicon Graphics -nimisen yrityksen kehittämä avoin ja alustariippumaton grafiikkarajapinta, jonka ensimmäinen versio julkaistiin vuonna 1992 [1]. Nykyisin OpenGL kehitystä hallinnoi Khronos Group -konsortio, jonka tehtävänä on kehittää avoimia ohjelmointirajapintoja [4] Direct3D Direct3D on Microsoftin OpenGL rajapinnalle kehittämä kilpailija, jonka ensimmäinen versio julkaistiin vuonna 1995 ja on nykyisin yksi käytetyimpiä grafiikkarajapintoja pelialalla [2]. Direct3D:tä on mahdollista käyttää vain Microsoftin omilla alustoilla kuten Windowsilla. Direct3D:stä julkaistiin vuonna 2015 versio 12, joka kilpailee Vulkanin kanssa ns. modernin grafiikkarajapinnan asemasta [5].
9 Mantle Mantle oli AMD näytönohjainvalmistajan ja DICE-pelistudion yhteinen yritys tehdä uusi grafiikkarajapinta, jonka tarkoituksena oli helpottaa nykyisten näytönohjaimien ominaisuuksien hyödyntämistä ohjelmoijille [6]. Mantlesta ei koskaan julkaistu julkista versiota ja sen kehitys lakkautettiin, kun AMD lahjoitti sen Khronos Groupille käytettäväksi Vulkanin pohjana [7]. 2.2 Näytönohjain Grafiikkarajapinnat on tarkoitettu hallitsemaan tietokoneen näytönohjainta. Näytönohjain on jokaisesta tietokoneesta löytyvä komponentti, jonka tehtävä on piirtää kuva näytölle, ja se myös sisältää kaikki 3D-grafiikan piirtämiseen vaaditut ominaisuudet. Näytönohjaimen rooli pelikäytössä on yleensä rajattu vain näytönohjaimelle tarkoitettujen ohjelmien eli varjostimien ajamiseen (käsitellään tarkemmin kohdassa 4.4.1), jotka määrittävät kuinka näytönohjain piirtää kuvan ruudulle (kuva 1). Kaikki muu pelin laskenta tapahtuu siis prosessorilla. Kuva 1. Näytönohjaimen rooli peleissä.
10 4 2.3 Yleiset ominaisuudet Kaikki grafiikkarajapinnat sisältävät ominaisuuden siirtää dataa näytönohjaimelle, kuten 3D-malleja ja tekstuureita. Tämän lisäksi niillä voi määrittää kuinka dataa käytetään esimerkiksi varjostimen kautta ja ne mahdollistavat lopullisen kuvan näyttämisen näytöllä. Kuitenkin näiden ominaisuuksien toteutus ja mahdollisten grafiikkarajapintaa tukevien alustojen määrä erottaa ne toisistaan. 2.4 Laiteläheisyys Modernit grafiikkarajapinnat, kuten Direct3D 12 ja Vulkan, mainostavat olevansa laiteläheisiä, mikä tarkoittaa, että enemmän työtä siirretään näytönohjaimen laiteajurista ohjelman vastuulle, mikä mahdollistaa erityisesti paremman optimoinnin ja tarkemman hallinnan näytönohjaimen resursseista, mutta tästä johtuen myös monimutkaistaa kuvien piirtämiseen tarvittavaa koodia [5].
11 5 3 VULKAN Vulkan on niin sanottu moderni laiteläheinen grafiikkarajapinta, jonka tarkoituksen on olla alustariippumaton ja helpottaa nykyisille näytönohjaimille optimoidun koodin tuottamista. Vulkanin tehtävänä on mahdollistaa 3D grafiikan piirtäminen näytönohjainta hyödyntämällä useilla eri käyttöjärjestelmillä ja laitteilla [8]. 3.1 Historia Vulkanin kehitys julkistettiin SIGGRAPH-tapahtumassa vuonna 2014, ja silloin se vielä tunnettiin nimellä glnext [9]. Vuonna 2015 Game Developer Conference tapahtumassa Vulkan julkistettiin virallisesti ja se sai nykyisen nimensä [10]. Vulkanin ensimmäinen julkinen versio julkaistiin 16. helmikuuta Se sisälsi versio 1.0-määritelmän ja ohjelmistonkehityskirjaston [11]. Vulkan pohjautuu suurilta osin AMD:n lahjoittamaan Mantle-grafiikkarajapintaan, jota AMD oli itse kehittänyt käytettäväksi yrityksen omilla näytönohjaimilla [7]. 3.2 Erot muihin grafiikkarajapintoihin Vulkan eroaa vanhemmista grafiikkarajapinnoista erityisesti sillä, että se on erittäin laiteläheinen ja piilottaa hyvin vähän nykyisen näytönohjaimen toimintaa ohjelmoijalta, kun taas vanhemmat grafiikkarajapinnat piilottavat enemmän näytönohjaimen toiminnasta laiteajureihin, mikä vaikeuttaa optimaalisen koodin tuottamista ja mahdollisten ohjelmistovirheiden löytämistä (kuva 2). Tästä johtuen Vulkanin käyttäminen vaatii huomattavasti enemmän koodin tuottamista ja ohjelmiston täytyy hyvin tarkasti määritellä, mitä näytönohjaimen ominaisuuksia se tulee hyödyntämään.
12 6 Kuva 2. Vulkan verrattuna vanhempiin grafiikkarajapintoihin [3]. Vulkanin suurin ero muihin moderneihin grafiikkarajapintoihin on sen alustariippumattomuus, ja tästä syystä se on saatavilla useilla eri alustoilla (kuva 3). Kuva 3. Vulkan verrattuna muihin moderneihin grafiikkarajapintoihin [3].
13 7 3.3 Vulkanin sopivuus Vulkan ei välttämättä ole paras valinta kaikkiin sovelluksiin erityisesti vaikeamman käytön takia. Vulkania tulisi erityisesti käyttää, jos suorituskyky on tärkeämpää kuin koodin monimutkaisuus (kuva 4). Kuva 4. Onko Vulkan sinulle sopiva [3]? Vulkan on myös hyvä valinta siinä tilanteessa, että haluaa tukea mahdollisimman monta eri alustaa, ilman että tarvitsee käyttää useaa eri grafiikkarajapintaa (kuva 3). 3.4 Monisäikeistys Monisäikeistyksellä tarkoitetaan työtaakan ajamista samanaikaisesti usealla eri prosessorin ytimellä, mikä mahdollistaa huomattavasti nopeamman prosessoinnin. Vulkanissa grafiikan piirtämisen monisäikeistys on otettu huomioon tarjoamalla ohjelmoijalle mahdollisuus hyödyntää nykyprosessorien useita ytimiä (kuva 5).
14 8 Kuva 5. Monisäikeistys Vulkanissa [3]. Vulkanissa monisäikeistys tapahtuu antamalla komentoja komentopuskureihin, joita jokainen prosessorin ydin voi luoda itsenäisesti, ja tämän jälkeen keräämällä ne yhteiseen komentojonoon, minkä kautta ne siirtyvät näytönohjaimelle (kuva 5).
15 9 4 VULKANIN KÄYTTÄMINEN Vulkanin ytimenä ovat oliot, joihin kaikki tarvittava tieto grafiikan piirtämistä varten tallennetaan. Muissa grafiikkarajapinnoissa osa tästä tiedosta on piilotettu laiteajureiden sisälle ja niiden sisältöön on todella vaikea vaikuttaa. Tämä tekee Vulkanin optimoinnista helpompaa, koska kaikki tarvittava tieto on täysin ohjelman hallinnassa. Vulkanin olioista tärkeimmät ovat ns. instanssi- ja laiteolio, joista instanssiolio sisältää kaiken tiedon Vulkanin nykyisestä tilasta ja laiteolio sisältää kaiken tarvittavan grafiikan piirtämistä varten. Vulkanissa muistinhallinta on ohjelmoijan vastuulla ja kaikki luodut oliot täytyy tuhota manuaalisesti, kun ohjelma ei niitä enää tarvitse. Seuraavaksi tutustutaan syvällisemmin Vulkanin eri osa-alueisiin käyttämällä hyödyksi C++-koodiesimerkkejä. Koodiesimerkeissä hyödynnetään GLFW-kirjastoa, joka helpottaa ikkunoiden luomista ja Vulkanin alustamista alustariippumattomasti [12]. Vulkanilla ohjelmien kehitys vaatii myös ohjelmistokehityskirjaston, joka on saatavilla esimerkiksi LunarG-yrityksen tarjoamana ilmaiseksi [13]. 4.1 Instanssi Vulkanin instanssiolio on toinen kahdesta oliosta, joiden avulla lähes kaikkia Vulkanin funktioita käytetään. Instanssiolio on linkki ohjelman ja Vulkan-kirjaston välillä [14].
16 Instanssin luominen Instanssiolion luomiseksi täytyy ensin kertoa Vulkan-kirjastolle hieman tietoa ohjelmasta. Aloitetaan luomalla VkApplicationInfo-olio, joka kertoo näytönohjaimen ajurille tietoa ohjelmasta [15]. VkApplicationInfo app = {}; app.stype = VK_STRUCTURE_TYPE_APPLICATION_INFO; app.papplicationname = "Ohjelman nimi"; app.applicationversion = 0; app.penginename = "Moottorin nimi"; app.engineversion = 0; app.apiversion = VK_API_VERSION_1_0; Tässä alustetaan ensin tyhjä VkApplicationInfo-olio ja sen jälkeen asetetaan tarvittavat tiedot siihen. Tämä on myös esimerkki Vulkan-kirjaston C-kielen juurista, mikä pakottaa, että jokaiselle oliolle täytyy asettaa stype-arvo mikä kertoo olion tyypin. Tämän arvon asettamatta jättäminen tai väärin asettaminen aiheuttaa virheen ja mahdollisesti estää ohjelman toimimisen. Kuitenkin kaikki tyyppeihin liittyvät makrot seuraavat samaa kaavaa ja ovat näin ollen helposti pääteltävissä. Seuraavaksi määritetään loput vaadittavat tiedot instanssiolion luomista varten [14]. VkInstance instance; uint32_t extensioncount; auto enabledextensions = glfwgetrequiredinstanceextensions(&extensioncount); VkInstanceCreateInfo instanceinfo = {}; instanceinfo.stype = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceinfo.papplicationinfo = &app; instanceinfo.enabledextensioncount = extensioncount; instanceinfo.ppenabledextensionnames = enabledextensions; VkResult result = vkcreateinstance(&instanceinfo, nullptr, &instance); Tässä määritetään VkInstanceCreateInfo-olio, johon asetetaan aikaisemmin määritetty olio ohjelman tiedosta [15]. Tämän lisäksi olioon täytyy määrittää, mitä laajennuksia sen tulisi käyttää. Vulkan-ohjelmalle täytyy aina määrittää alustariippuvaiset laajennukset, jotka mahdollistavat kommunikoinnin alustan ikkunoiden
17 11 kanssa. Tämän helpottamiseksi GLFW-kirjasto tarjoaa funktion, joka palauttaa tarvittavat laajennukset eri alustoilla [16]. Lopuksi vkcreateinstance-funktio luo instanssiolion määritetyillä tiedoilla ja asettaa sen instance-muuttujaan, joka tulisi säilyttää koko ohjelman elinajan [15]. Tämä funktio ja monet muut Vulkanin funktiot myös palauttavat palautusarvona virhekoodin, jossa VK_SUCCESS-arvo tarkoittaa onnistumista ja kaikki muut arvot jotakin virhettä [14]. Instanssi tulee tuhota manuaalisesti käyttämällä funktiota vkdestroyinstance [14] Validointi ja virheenkorjaus Vulkanissa virheentarkastus täytyy ottaa käyttöön manuaalisesti. Tämä on tehty siksi, että tarkastus ei ole ilmaista, vaan se hidastaa ohjelmaa. Virheentarkastus otetaan käyttöön lisäämällä vkcreateinstanceinfo-olioon halutut virheentarkastusominaisuudet [14]. const std::vector<const char*> validationlayers = { "VK_LAYER_LUNARG_standard_validation", }; instace_info.enabledlayercount = validationlayers.size(); instace_info.ppenabledlayernames = validationlayers.data(); Tässä otetaan käyttöön niin kutsuttu standardivalidointikerros, joka ottaa käyttöön yleisimmät virheentarkastusominaisuudet. Myös muita virheentarkastusominaisuuksia on olemassa ja niitä voi ottaa käyttöön tarpeen mukaan [17]. Tuetut virheentarkastusominaisuudet voi listata funktiolla vkenumerateinstance- LayerProperties, joka palauttaa listan kaikista kyseisellä laitteella/alustalla tuetuista ominaisuuksista. Oikeissa sovelluksissa tulisikin tarkistaa, ovatko vaaditut ominaisuudet tuettuja ennen niiden käyttämistä [15]. Tämän lisäksi vkcreateinstanceinfo-olioon listattuihin laajennuksiin täytyy lisätä "VK_EXT_debug_report", joka mahdollistaa sen, että voidaan lukea Vulkanin palauttamat virheviestit [14]. Seuraavaksi rekisteröidään funktio, jolla luetaan palautetut virheviestit.
18 12 auto CreateDebugReportCallbackExt = reinterpret_cast<pfn_vkcreatedebugreportcallbackext>( vkgetinstanceprocaddr(instance, "vkcreatedebugreportcallbackext")); VkDebugReportCallbackEXT debugreportcallback; VkDebugReportCallbackCreateInfoEXT callbackcreateinfo = {}; callbackcreateinfo.stype = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; callbackcreateinfo.pfncallback = DebugCallback; callbackcreateinfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT CreateDebugReportCallbackExt(instance, &callbackcreateinfo, nullptr, &debugreportcallback); Tässä rekisteröidään funktio, joka lukee mahdolliset virheviestit. Koska virheidentarkastus on laajennus, täytyy vkcreatedebugreportcallbackext-funktio ladata manuaalisesti käyttämällä instanssilaajennusfunktioiden lataamiseen tarkoitettua vkgetinstanceprocaddr-funktiota [14]. Tämän jälkeen luodaan VkDebugReportCallbackCreateInfoEXT-olio ja siihen asetetaan funktio, jota Vulkan kutsuu virheen sattuessa, ja vaaditut virheviestien tasot. Käyttämällä kyseistä oliota lopuksi rekisteröidään virheentarkastusfunktio käyttämällä aikaisemmin ladattua laajennusfunktiota ja tallennetaan VkDebug- ReportCallbackEXT-kahva mahdollista myöhempää käyttöä varten, kuten esimerkiksi rekisteröinnin poistaminen [14]. Virheviestien rekisteröinti tulee poistaa manuaalisesti käyttämällä vkdestroy- DebugReportCallbackEXT-funktiota, joka kuten virheviestin lukemisen luontiin käytetty funktio tulee ladata manuaalisesti [14]. 4.2 Laiteobjekti Vulkanissa näytönohjaimen käyttäminen vaatii laiteobjektin luomisen, joka määrittää näytönohjaimelta vaaditut ominaisuudet ja mahdollistaa erilaisten komentojen (esim. kuvien piirtäminen) lähettämisen näytönohjaimelle [18, s. 3].
19 Fyysisen laitteen valinta Laiteobjektin luomisessa täytyy ensimmäiseksi valita, mitä fyysistä näytönohjainta käytetään ja tallentaa se kahvaan [18, s. 7]. uint32_t gpucount; vkenumeratephysicaldevices(instance, &gpucount, nullptr); std::vector<vkphysicaldevice> physicaldevices(gpucount); vkenumeratephysicaldevices(instance, &gpucount, physicaldevices.data()); VkPhysicalDevice gpu = physicaldevices[0]; Tässä listataan kaikki Vulkania tukevat näytönohjaimet ja tallennetaan listasta ensimmäisen kahva tulevaa käyttöä varten. Todellisuudessa, jos listassa on enemmän kuin yksi näytönohjain, olisi hyvä idea tarkistaa listasta paras näytönohjain käyttämällä vkgetphysicaldeviceproperties- ja vkgetphysicaldevicefeaturesfunktiota ja verrata näytönohjaimien ominaisuuksia ohjelmassa tarvittuihin ominaisuuksiin [15] Jonoperheet Vulkanissa lähes kaikki operaatiot aina kuvien piirtämisestä tekstuurien lataamiseen näytönohjaimen muistiin vaativat komentojonojen käyttämistä. Komentojonot on määritetty erilaisiin perheisiin, jotka tukevat vain tiettyjä operaatioita. Grafiikan piirtämiseksi täytyy löytää jonoperhe, joka tukee grafiikkaoperaatioita [18, s ] uint32_t queuecount; vkgetphysicaldevicequeuefamilyproperties(gpu, &queuecount, nullptr); std::vector<vkqueuefamilyproperties> queuefamilies(queuecount); vkgetphysicaldevicequeuefamilyproperties(gpu, &queuecount, queuefamilies.data()); uint32_t graphicsqueue = 0; for (size_t i = 0; i < queuefamilies.size(); i++) { const auto& queuefamily = queuefamilies[i];
20 14 if (queuefamily.queuecount >= 0 && queuefamily.queueflags & VK_QUEUE_GRAPHICS_BIT) { graphicsqueue = i; break; } } uint32_t graphicsqueueindex = graphicsqueue; Tässä haetaan kaikki jonoperheet käyttämällä vkgetphysicaldevicequeuefamilyproperties-funktiota ja tarkistetaan, mikä niistä tukee grafiikkaoperaatioita vertaamalla sitä VK_QUEUE_GRAPHICS_BIT-arvoon [15]. Lopuksi sopiva jonoperhe tallennetaan muistiin myöhempää käyttöä varten [14]. Tämän lisäksi tulisi myös löytää jonoperhe, joka tukee kuvien esittämistä näytöllä, siinä tapauksessa, että kuvien piirtäminen näytölle on tavoitteena. Tämä onnistuu käyttämällä funktiota vkgetphysicaldevicesurfacesupportkhr [14]. Tulee kuitenkin huomioida, että kyseisen funktion käyttäminen vaatii ikkunan pinnan luomisen, joka käydään läpi myöhemmin Laiteobjektin luominen Laiteobjektin luomiseksi täytyy ensimmäiseksi määrittää kaikki vaaditut ominaisuudet. Ensimmäiseksi tulee määrittää halutut komentojonoperheet. VkDeviceQueueCreateInfo queuecreateinfo = {}; queuecreateinfo.stype = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queuecreateinfo.queuefamilyindex = graphicsqueueindex; queuecreateinfo.queuecount = 1; float queuepriorities = 1.0f; queuecreateinfo.pqueuepriorities = &queuepriorities; Tässä määritetään grafiikkaoperaatioita tukeva jonoperhe VkDevice- QueueCreateInfo-olioon ja annetaan sille prioriteetti, jossa 0,0 on alhaisin prioriteetti ja 1,0 korkein [15]. Tämän lisäksi olisi hyvä myös määrittää jonoperhe kuvien esittämiseksi niitä tilanteita varten, jolloin ei löydy jonoperhettä, joka tukee kuvien esittämistä ja grafiikkaoperaatioita yhtä aikaa.
21 15 Tämän jälkeen voidaan määrittää mahdolliset näytönohjaimelta halutut ominaisuudet VkPhysicalDeviceFeatures-olioon [15]. Lopuksi määritetään itse laiteobjektin luomiseen vaadittu olio ja luodaan laiteobjekti. VkDeviceCreateInfo devicecreateinfo = {}; devicecreateinfo.stype = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; devicecreateinfo.queuecreateinfocount = 1; devicecreateinfo.pqueuecreateinfos = &queuecreateinfo; devicecreateinfo.enabledlayercount = enabledlayernames.size(); devicecreateinfo.ppenabledlayernames = enabledlayernames.data(); devicecreateinfo.penabledfeatures = nullptr; VkDevice device; vkcreatedevice(gpu, &devicecreateinfo, nullptr, &device); Tässä määritetään VkDeviceCreateInfo-olio, johon asetetaan jonoperheen luomiseen vaadittu olio sekä mahdolliset virheentarkastuskerrokset [15]. Tämän lisäksi luodaan laiteobjeki käyttämällä vkcreatedevice-funktiota ja se tallennetaan tulevaa käyttöä varten [14]. Laiteobjekti tulee tuhota manuaalisesti käyttämällä vkdestroydevice-funktiota [14] Komentojonokahva Laiteobjektin luominen luo myös automaattisesti kaikki pyydetyt komentojonoperheet ja niiden käyttämiseksi täytyy pyytää Vulkanilta kahva käyttämällä vkgetdevicequeue-funktiota ja tallentamalla kahva myöhempää käyttöä varten [15]. 4.3 Kuvan esittäminen Ennen kuvien piirtämistä täytyy olla mahdollisuus esittää kuva näytöllä. Tätä varten Vulkan täytyy yhdistää ohjelman ikkunaan, jotta kuvat voidaan esittää ikkunassa. Tähän liittyen tulee myös luoda vaihtoketju joka sisältää kuvat, joihin lopullinen piirtäminen tapahtuu ja ne esitetään ikkunassa.
22 Ikkunan pinta Vulkanissa ikkunassa olevaa aluetta, johon piirtäminen on mahdollista, kutsutaan pinnaksi [18, s ]. Ikkunan pinnan luominen on alustasta riippuvainen operaatio, mutta myös ikkunan luomiseen käytetty GLFW-kirjasto tarjoaa glfwcreatewindowsurface-funktion, joka luo ikkunan pinnan alustariippumattomasti [16]. Ikkunan pinta on myös mahdollista luoda manuaalisesti esimerkiksi Windowsalustalla käyttämällä vkcreatewin32surfacekhr-funktiota ja syöttämällä sille kaikki ikkunasta vaaditut tiedot [14]. Riippumatta tavasta, miten ikkunan pinta on luotu, se tulee manuaalisesti tuhota käyttämällä vkdestroysurfacekhr-funktiota [14] Vaihtoketju Vaihtoketjulla tarkoitetaan tapaa esittää yleisesti kaksi tai joskus enemmän kuvaa niin, että yksi kuva on esillä näytöllä ja samanaikaisesti toiseen kuvaan piirretään ja tämän jälkeen kuvat vaihdetaan (kuva 6). Tämä estää käyttäjään näkemästä kuvaa kesken piirto-operaation, jolloin kuva voisi olla keskeneräinen [18, s. 143.]
23 17 Kuva 6. Esimerkki vaihtoketjun toiminnasta [19]. Vaihtoketjun luomiseksi täytyy ensimmäiseksi ottaa laiteobjektia luodessa käyttöön "VK_KHR_swapchain"-laajennus, joka mahdollistaa vaihtoketjun luomisen. Tämä siitä syystä, että kaikki näytönohjaimet eivät välttämättä tue kuvien esittämistä näytöllä, jos ne ovat esimerkiksi tarkoitettu serverikäyttöön [14]. Mahdollisuuden vaihtoketjun luomiseen voi tarkistaa vkenumeratedeviceextensionproperties-funktiolla [15]. Seuraavaksi tulee tarkistaa, mitä kuvaformaatteja näytönohjain tukee. Tämä onnistuu funktioilla vkgetphysicaldevicesurfaceformatskhr ja vkgetphysical- DeviceSurfacePresentModesKHR [14]. Kun sopiva kuvaformaatti on löydetty ja tallennettu mahdollista tulevaa käyttöä varten, voidaan siirtyä luomaan vaihtoketju.
24 18 VkSurfaceCapabilitiesKHR surfacecapabilities; vkgetphysicaldevicesurfacecapabilitieskhr(gpu, surface, &surfacecapabilities); VkExtent2D swapchainextent; if (surfacecapabilities.currentextent.width == std::numeric_limits<uint32_t>::max()) { swapchainextent.width = windowwidth; swapchainextent.height = windowheight; } else { swapchainextent = surfacecapabilities.currentextent; } uint32_t desirednumberofswapchainimages = surfacecapabilities.minimagecount + 1; if (surfacecapabilities.maximagecount > 0 && desirednumberofswapchainimages > surfacecapabilities.maximagecount) { desirednumberofswapchainimages = surfacecapabilities.maximagecount; } VkSwapchainCreateInfoKHR swapchaincreateinfo = {}; swapchaincreateinfo.stype = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchaincreateinfo.surface = surface; swapchaincreateinfo.minimagecount = desirednumberofswapchainimages; swapchaincreateinfo.imageformat = VK_FORMAT_B8G8R8A8_UNORM; swapchaincreateinfo.imagecolorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; swapchaincreateinfo.imageextent = swapchainextent; swapchaincreateinfo.imageusage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchaincreateinfo.pretransform = surfacecapabilities.currenttransform; swapchaincreateinfo.compositealpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchaincreateinfo.imagearraylayers = 1; swapchaincreateinfo.imagesharingmode = VK_SHARING_MODE_EXCLUSIVE; swapchaincreateinfo.queuefamilyindexcount = 0; swapchaincreateinfo.pqueuefamilyindices = nullptr; swapchaincreateinfo.presentmode = VK_PRESENT_MODE_FIFO_KHR; swapchaincreateinfo.oldswapchain = VK_NULL_HANDLE; swapchaincreateinfo.clipped = VK_TRUE; vkcreateswapchainkhr(device, &swapchaincreateinfo, nullptr, &swapchain); Tässä kysytään aluksi näytönohjaimelta, mitä rajoituksia vaihtoketjun luomiseen liittyy käyttämällä vkgetphysicaldevicesurfacecapabilitieskhr-funktiota ja käytetään tätä informaatiota selvittämään vaihtoketjun kuvien ihanteellinen resoluutio ja montako kuvaa tulisi luoda, jotta kuvien vaihtaminen onnistuu [14]. Sen jälkeen
25 19 luodaan VkSwapchainCreateInfoKHR-olio ja siihen asetetaan haluttujen kuvien määrä, resoluutio ja kuvaformaatti [14]. Tässä esimerkissä asetetaan arvot yleisimmin saatavilla oleviin kuvaformaatteihin ja asetuksiin, mutta todellisuudessa tulisi tarkistaa paras saatavilla oleva formaatti [18, s ]. Olioon tulee myös määrittää vanhentunut vaihtoketju, siinä tilanteessa, että vaihtoketjua ollaan luomassa uudelleen esimerkiksi ikkunan koon muutoksen takia. Lopuksi vaihtoketju luodaan käyttämällä vkcreateswapchainkhr-funktiota [14]. Lopuksi haetaan vaihtoketjun luonnin yhteydessä luodut kuvat vkgetswapchain- ImagesKHR-funktiolla [14]. Vaihtoketju tulee tuhota manuaalisesti käyttämällä vkdestroyswapchainkhrfunktiota [14] Kuvanäkymä Vulkanissa kaikkien kuvien muokkaamiseen tulee luoda kuvanäkymä, joka on kirjaimellisesti näkymä kyseiseen kuvaan. Kuvanäkymä määrittää, mitä aluetta kuvasta halutaan muokata ja miten kuvaa tulisi käsitellä (esim. 2-ulotteinen tekstuuri). Myöskin vaihtoketjun kuvien käyttämiseen tulee luoda niille kuvanäkymä. for (size_t i = 0; i < swapchainimagecount; i++) { VkImageViewCreateInfo colorimageview = {}; colorimageview.stype = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; colorimageview.format = VK_FORMAT_B8G8R8A8_UNORM; colorimageview.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; colorimageview.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; colorimageview.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; colorimageview.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; colorimageview.subresourcerange.aspectmask = VK_IMAGE_ASPECT_COLOR_BIT; colorimageview.subresourcerange.basemiplevel = 0; colorimageview.subresourcerange.levelcount = 1; colorimageview.subresourcerange.basearraylayer = 0; colorimageview.subresourcerange.layercount = 1; colorimageview.viewtype = VK_IMAGE_VIEW_TYPE_2D; colorimageview.image = swapchainimages[i]; vkcreateimageview(device, &colorimageview, nullptr, &swapchainbuffers[i].imageview);
26 20 } Tässä luodaan yksinkertainen kuvanäkymä jokaiselle vaihtoketjun kuvalle kuvien piirtämistä varten. Aluksi luodaan VkImageViewCreateInfo-olio ja siihen asetetaan yksinkertaiset arvot, jotka mahdollistavat yksinkertaisen koko kuvaan piirtämisen [14]. Tämän jälkeen kuvanäkymä luodaan vkcreateimageview-funktiolla [15]. Kuvanäkymä tulee tuhota manuaalisesti käyttämällä vkdestroyimageviewfunktiota [14]. 4.4 Grafiikkaliukuhihna Grafiikkaliukuhihnalla tarkoitetaan Vulkanissa niitä operaatioita, jotka läpikäymällä piirrettävä data, kuten tekstuurit ja 3D-mallit, muuttuvat pikseleiksi ruudulla. Tähän sisältyvät mm. varjostimet, piirtokierrokset ja kuvapuskurit. Toisin kuin muissa grafiikkarajapinnoissa, Vulkanin grafiikkaliukuhihna ei sisällä mitään oletusarvoja. Tästä johtuen grafiikkaliukuhihnaa luodessa täytyykin kaikki halutut ominaisuudet määrittää eksplisiittisesti [18, s ] Varjostimet Varjostimella tarkoitetaan ohjelmaa, joka ajetaan näytönohjaimella ja sen tehtävänä on määrittää, kuinka näytönohjaimelle lähetetty data muutetaan pikseleiksi [20]. Erityisesti 3D-grafiikassa tähän yleensä myös sisältyy valaistuksen ja varjojen laskenta mistä varjostimen nimi myös juontuu. Vulkanissa varjostimet yleensä kirjoitetaan GLSL-kieltä käyttäen ja ne tulee ennen lataamista kääntää SPIR-V-formaattiin [18, s ], joka onnistuu esimerkiksi Vulkanin ohjelmistokehityspaketin mukana tulevalla glslangvalidator-sovelluksella [21]. Vulkan tukee useita erityyppisiä varjostimia, kuten esimerkiksi verteksi, pikseli ja geometria varjostimia. Näistä kuvan piirtämiseksi verteksi ja pikseli varjostimet ovat pakolliset.
27 21 Varjostimien lataaminen on suhteellisen yksinkertaista. Ensin varjostin luetaan tiedostosta, ja sen jälkeen kerrotaan Vulkanille, minkä tyyppinen varjostin on kyseessä. std::ifstream file; file.open("triangle.vert.spv", std::ios::binary std::ios::ate); uint32_t size = static_cast<uint32_t>(file.tellg()); file.seekg(0, std::ios::beg); std::vector<char> vertexdata; vertexdata.resize(size); file.read(vertexdata.data(), size); file.close(); VkShaderModuleCreateInfo modulecreateinfo = {}; modulecreateinfo.stype = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; modulecreateinfo.codesize = size; modulecreateinfo.pcode = reinterpret_cast<uint32_t*>(vertexdata.data()); VkShaderModule vertexmodule; vkcreateshadermodule(vulkan.device, &modulecreateinfo, nullptr, &vertexmodule); VkPipelineShaderStageCreateInfo vertexshaderstageinfo = {}; vertexshaderstageinfo.stype = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertexshaderstageinfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertexshaderstageinfo.module = vertexmodule; vertexshaderstageinfo.pname = "main"; Tässä luetaan aluksi varjostimen koodi tiedostosta (liite 1). Tämän jälkeen luodaan VkShaderModuleCreateInfo-olio, jonka avulla varjostimen koodista luodaan VkShaderModule-kahva [15]. VkPipelineShaderStageCreateInfo-olioon määritetään varjostimen tyyppi, aiemmin luotu kahva ja funktion nimi, josta varjostimen koodin ajaminen aloitetaan [15]. Samalla periaatteella tulisi myös ladata pikselivarjostin (liite 2) ja tallentaa molemmat VkPipelineShaderStageCreateInfo-oliot myöhempää grafiikkaliukuhihnan luomista varten. Grafiikkaliukuhihnan luonnin jälkeen tulee VkShaderModule-oliot tuhota käyttämällä vkdestroyshadermodule-funktiota [14].
28 Piirtokierrokset Vulkanissa piirtokierroksilla tarkoitetaan tapaa piirtää kuva kerroksittain. Esimerkiksi ensimmäinen kierros voisi piirtää yksinkertaisen kuvan ja toinen kierros lisätä kuvaan valaistuksen. Piirtokierroksien määrä on täysin riippuivainen ohjelmasta, mutta jokaisessa ohjelmassa täytyy olla vähintään yksi kuvan piirtämistä varten [18, s. 230.] Yksinkertainen piirtokierros luodaan aluksi määrittämällä siihen liittyvien kuvien tyypit ja tämän jälkeen määrittämällä jokainen piirtokierros yksitellen, jonka jälkeen nämä yhdistävä piirtokierros voidaan luoda. Monimutkaisemmassa piirtokierroksessa voitaisiin myös määrittää mahdolliset yksittäisen piirtokierroksien toisistaan riippuvuudet, jos esimerkiksi toinen piirtokierros on riippuvainen ensimmäisen lopputuloksesta [18, s ]. VkAttachmentDescription attachment = {}; attachments[0].format = format; attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; attachments[0].loadop = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[0].storeop = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilloadop = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilstoreop = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[0].initiallayout = VK_IMAGE_LAYOUT_UNDEFINED; attachments[0].finallayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; Tässä esimerkissä luodaan aluksi määritelmä yhdelle väridataa sisältävälle kuvalle käyttämällä VkAttachmentDescription-oliota [15]. Muun tyyppisiä kuvia olisivat mm. syvyysdataa sisältävä kuva. Olioon asetetaan aluksi vaihtoketjua luodessa valittu kuvaformaatti ja tämän jälkeen määritetään, mitä Vulkan tekee kuvalle piirron aloitusvaiheessa ja sen lopussa. Tässä tapauksessa VK_ATTACHMENT_LOAD_OP_CLEAR-arvo tarkoittaa, että kuva tyhjennetään piirron alkuvaiheessa ja VK_ATTACHMENT_STORE_OP_STORE-arvo kehottaa Vulkania tallentamaan kuvan muistiin piirron lopussa. Lopuksi määritetään, että kuvaa käytetään kuvien esittämisen lähteenä. Seuraavaksi tulee määrittää kuvamääritelmälle viittaus, jotta yksittäiset piirtokierrokset voivat viitata siihen.
29 23 VkAttachmentReference colorreference = {}; colorreference.attachment = 0; colorreference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; Tässä määritetään yksinkertainen viittaus käyttämällä VkAttachmentReferenceolio, johon asetetaan kuvamääritelmän indeksi ja tyyppi [15]. Tässä tapauksessa kuvamääritelmiä on vain yksi, joten indeksi on nolla. Seuraavaksi tulee määrittää yksittäinen piirtokierros. VkSubpassDescription subpass = {}; subpass.pipelinebindpoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorattachmentcount = 1; subpass.pcolorattachments = &colorreference; Yksittäinen piirtokierros määritetään käyttämällä VkSubpassDescription-oliota [15]. Tässä erimerkissä siihen asettaan vain yksi väridataa sisältävän kuvan viittaus ja määritetään, että se on grafiikan piirtämiseen tarkoitettu piirtokierros. Lopuksi voidaan luoda itse piirtokierros. VkRenderPassCreateInfo renderpassinfo = {}; renderpassinfo.stype = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderpassinfo.attachmentcount = 1; renderpassinfo.pattachments = attachment; renderpassinfo.subpasscount = 1; renderpassinfo.psubpasses = &subpass; renderpassinfo.dependencycount = 0; renderpassinfo.pdependencies = nullptr; VkRenderPass renderpass; vkcreaterenderpass(device, &renderpassinfo, nullptr, &renderpass); Tässä määritetään aluksi piirtokierros käyttämällä VkRenderPassCreateInfo-oliota [15]. Siihen asetetaan kuvamääritelmät ja kaikki yksittäiset piirtokierrokset, sekä mahdolliset piirtokierroksien riippuvuudet. Lopuksi piirtokierros luodaan vkcreaterenderpass-funktiolla ja se tallennetaan VkRenderPass-kahvaan [15]. Piirtokierrokset tulee manuaalisesti tuhota käyttämällä vkdestroyrenderpassfunktiota [14].
30 Kuvapuskurit Kuvapuskuri on olio, jonka tarkoituksena on määrittää, mihin kuviin grafiikkaliukuhihna piirtää [18, s. 237]. Kuvapuskuriolio luodaan viittaamalla käytettävään piirtokierrokseen ja vaihtoketjun kuvan kuvanäkymään. Kuvapuskuria on mahdollista käyttää myös muiden piirtokierroksien kanssa, jos ne sisältävät samanlaiset viittaukset käytettyihin kuviin. On myös mahdollista määrittää kuvia, joita ei välttämättä käytetä siinä tapauksessa, että halutaan tukea useaa eri piirtokierrosta, joilla on eri määrä käytössä olevia kuvia [18, s. 238]. std::vector<vkframebuffer> framebuffers(swapchainbuffers.size()); for (size_t i = 0; i < swapchainbuffers.size(); i++) { VkImageView attachments[] = { swapchainimageviews[i] }; VkFramebufferCreateInfo framebuffercreateinfo = {}; framebuffercreateinfo.stype = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebuffercreateinfo.renderpass = renderpass; framebuffercreateinfo.attachmentcount = 1; framebuffercreateinfo.pattachments = attachments; framebuffercreateinfo.width = windowwidth; framebuffercreateinfo.height = windowheight; framebuffercreateinfo.layers = 1; vkcreateframebuffer(device, &framebuffercreateinfo, nullptr, &framebuffers[i]); } Tässä luodaan vaihtoketjun kuvien määrän verran kuvapuskureita. VkFramebufferCreateInfo-olioon [15] määritetään käytettävä piirtokierros ja vaihtoketjun kuvanäkymä. Koska kuvapuskuria käytetään kuvien piirtämiseen, määritetään siihen myös vaihtoketjun kuvien eli ikkunan resoluution. Lopuksi jokainen kuvapuskuri luodaan vkcreateframebuffer-funktiolla [15]. Kuvapuskurit tulee manuaalisesti tuhota käyttämällä vkdestroyframebufferfunktiota [14].
31 Grafiikkaliukuhihnan tila Kuten aiemmin mainittu, Vulkanin grafiikkaliukuhihna ei sisällä mitään oletusarvoja, joten kaikki arvot tulee määrittää itse. Grafiikkaliukuhihnan määritettävään tilaan kuuluu mm. Verteksidatan formaatti, piirtämisen tyyppi (esim. kolmio tai viiva), kuvaportin koko ja syvyystestauksen asetukset. Osa grafiikkaliukuhihnan tilasta on myös mahdollista määrittää ns. dynaamiseksi tilaksi, eli se täytyy määrittää aina ennen kuvan piirtämistä. Tämä myös tarkoittaa, että sitä voidaan muuttaa kesken ohjelman ajon ilman grafiikkaliukuhihnan uudelleen luomista. Yksinkertaisen kuvan piirtämiseksi grafiikkaliukuhihnan tilan voi määrittää seuraavasti. VkPipelineInputAssemblyStateCreateInfo inputassemblystate = {}; inputassemblystate.stype = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputassemblystate.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; Tässä määritetään piirtämisen tyypiksi lista kolmiota käyttämällä VkPipeline- InputAssemblyStateCreateInfo-oliota [15]. Seuravaksi määritetään rasterisoinnin ominaisuudet. VkPipelineRasterizationStateCreateInfo rasterizationstate = {}; rasterizationstate.stype = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizationstate.polygonmode = VK_POLYGON_MODE_FILL; rasterizationstate.cullmode = VK_CULL_MODE_NONE; rasterizationstate.frontface = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizationstate.depthclampenable = VK_FALSE; rasterizationstate.rasterizerdiscardenable = VK_FALSE; rasterizationstate.depthbiasenable = VK_FALSE; rasterizationstate.linewidth = 1.0f; Tässä määritetään rasterisoinnin ominaisuudet käyttämällä VkPipelineRasterizationStateCreateInfo-oliota [15]. Aluksi määritettään miten kolmiot tulisi piirtää. Tässä esimerkissä VK_POLYGON_MODE_FILL-arvo tarkoittaa, että kolmiot piirretään täytettyinä. Muita vaihtoehtoja ovat pelkät reunaviivat tai pisteet. Tämän jälkeen määritetään tulisiko piilossa olevia kolmiota jättää piirtämättä ja myöskin määritetään minkälaiset kolmiot ovat mahdollisesti piilossa. Tässä esimerkissä
32 26 piiretään yksinkertaisesti kaikki kolmiot. Lopuksi määritetään monimutkaisemmat ominaisuudet pois päältä yksinkertaista piirtoa varten. Seuraavaksi määritetään kuinka värit tulisi sekoittaa. VkPipelineColorBlendAttachmentState blendattachmentstate[1] = {}; blendattachmentstate[0].colorwritemask = 0xf; blendattachmentstate[0].blendenable = VK_FALSE; VkPipelineColorBlendStateCreateInfo colorblendstate = {}; colorblendstate.stype = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorblendstate.attachmentcount = 1; colorblendstate.pattachments = blendattachmentstate; Tässä määritettään aluksi värien sekoittaminen VkPipelineColorBlendAttachmentState-olioon. Tässä esimerkissä ei käytetä värien sekoitusta, joten se laitetaan pois käytöstä. Tämän jälkeen värien sekoitus tulee määrittää grafiikkaliukuhihnalle VkPipelineColorBlendStateCreateInfo-olioon [15.] Seuraavaksi määritetään kuvaportti ja siihen piirrettävä alue. std::vector<vkdynamicstate> dynamicstates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; VkPipelineDynamicStateCreateInfo dynamicstate = {}; dynamicstate.stype = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicstate.pdynamicstates = dynamicstates.data(); dynamicstate.dynamicstatecount = dynamicstates.size(); VkPipelineViewportStateCreateInfo viewportstate = {}; viewportstate.stype = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportstate.viewportcount = 1; viewportstate.scissorcount = 1; Tässä määritetään esimerkin vuoksi kuvaportti ja siihen piirrettävä alue käyttämään dynaamista tilaa VkPipelineDynamicStateCreateInfo-olion avulla [15]. Sen lisäksi määritetään grafiikkaliukuhihnassa käytettäväksi yksi kuvaportti käyttämällä VkPipelineViewportStateCreateInfo-oliota [15]. Tämä sen takia, että joillakin näytönohjaimilla on mahdollista käyttää useampaa kuvaporttia, mutta tämä vaatii laajennuksen ottamisen käyttöön laitteen luomisen yhteydessä. Lopullinen kuvaportti määritetään piirron yhteydessä, koska se käyttää dynaamista tilaa.
33 27 Seuraavaksi määritetään mahdolliset moniotannan ominaisuudet. VkPipelineMultisampleStateCreateInfo multisamplestate = {}; multisamplestate.stype = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisamplestate.psamplemask = nullptr; multisamplestate.rasterizationsamples = VK_SAMPLE_COUNT_1_BIT; Tässä esimerkissä ei käytetä moniotantaa, joten se määritetään pois käytöstä käyttämällä VkPipelineMultisampleStateCreateInfo-oliota [15]. Seuraavaksi täytyy määrittää grafiikkaliukuhihnan asettelu, jonka avulla voidaan siirtää arvoja varjostimeen. Tähän tutustutaan tarkemmin myöhemmin, joten tässä luodaan vain tyhjä asettelu. VkPipelineLayout pipelinelayout VkPipelineLayoutCreateInfo pipelinelayoutcreateinfo = {}; pipelinelayoutcreateinfo.stype = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; vkcreatepipelinelayout(vulkan.device, &pipelinelayoutcreateinfo, nullptr, &pipelinelayout); Tässä luodaan tyhjä grafiikkaliukuhihnan asettelu käyttämällä VkPipeline- LayoutCreateInfo-oliota ja tallennetaan se VkPipelineLayout-kahvaan [15]. Grafiikkaliukuhihnan asettelu tulee manuaalisesti tuhota käyttämällä vkdestroypipelinelayout-funktiota [14]. Grafiikkaliukuhihna tarvitsee myös määritelmän sille syötettävästä verteksidatasta. Tämä käydään läpi myöhemmin datan siirtoon liittyvässä osiossa, joten tässä luodaan vain tyhjän määritelmä. VkPipelineVertexInputStateCreateInfo vertexinputstate = {}; vertexinputstate.stype = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; Tässä luodaan tyhjä verteksidatan määritys käyttämällä VkPipelineVertexInputStateCreateInfo-oliota [15]. Tämän lisäksi voitaisiin myös määrittää esimerkiksi syvyyspuskurin ominaisuudet käyttämällä VkPipelineDepthStencilStateCreateInfo-oliota, mutta koska tämä esimerkki ei käytä syvyysdataa kuvan piirtämisessä, voidaan lopullisen grafiikkaliukuhihnan luonnissa jättää arvo asettamatta.
34 Grafiikkaliukuhihnan luominen Grafiikkaliukuhihan luomiseksi otetaan kaikki edellä mainitut ominaisuudet ja yhdistetään ne lopullisen grafiikkahihnan luomiseksi. VkGraphicsPipelineCreateInfo pipelinecreateinfo = {}; pipelinecreateinfo.stype = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelinecreateinfo.layout = pipelinelayout; pipelinecreateinfo.renderpass = renderpass; pipelinecreateinfo.stagecount = shaderstages.size(); pipelinecreateinfo.pstages = shaderstages.data(); pipelinecreateinfo.pvertexinputstate = &vertexinputstate; pipelinecreateinfo.pinputassemblystate = &inputassemblystate; pipelinecreateinfo.prasterizationstate = &rasterizationstate; pipelinecreateinfo.pcolorblendstate = &colorblendstate; pipelinecreateinfo.pmultisamplestate = &multisamplestate; pipelinecreateinfo.pviewportstate = &viewportstate; pipelinecreateinfo.pdepthstencilstate = nullptr; pipelinecreateinfo.pdynamicstate = &dynamicstate; VkPipeline pipeline; vkcreategraphicspipelines(device, VK_NULL_HANDLE, 1, &pipelinecreateinfo, nullptr, &pipeline); Tässä määritetään grafiikkaliukuhihna käyttämällä VkGraphicsPipelineCreate- Info-oliota [15]. Olioon asetetaan aluksi aikaisemmin luodut grafiikkaliukuhihnan asetelmamääritys ja piirtokierros. Tämän jälkeen määritetään aikaisemmin ladatut varjostimet ja lopuksi määritetään kaikki aikaisemmin määritelty grafiikkaliukuhihnan tila. Tämän jälkeen grafiikkaliukuhihna luodaan vkcreategraphicspipelinesfunktiolla [15]. Tämä funktio eroaa jonkin verran muista Vulkanin funktiosta siinä, että sillä voidaan luoda useita grafiikkaliukuhihnoja yhdellä kertaa, mistä johtuen siihen tulee määrittää luotavien liukuhihnojen määrä (tässä tapauksessa yksi). Tässä myöskin voitaisiin käyttää grafiikkaliukuhihnan välimuistia (VkPipelineCache), joka mahdollistaa mm. grafiikkaliukuhihnojen tallentamisen tiedostoon ja tämän tiedoston hyödyntämistä myöhemmässä vaiheessa grafiikkaliukuhihnan luonnin nopeuttamiseksi [18, s ]. Grafiikkaliukuhihna tulee manuaalisesti tuhota käyttämällä vkdestroypipelinefunktiota [14].
35 Komennot Vulkanissa komentoja, kuten piirtäminen ja datan siirtäminen näytönohjaimelle, ei kutsuta suoraan, vaan ne kerätään komentopuskureihin, jotka komentojonojen kautta lähetetään näytönohjaimelle. Tämä mahdollistaa sen, että komennot ja niiden tarvitsema laskenta, voidaan tallentaa käyttämällä useita säikeitä yhtäaikaisesti ja tämän jälkeen lähettää yhtenä kokonaisuutena näytönohjaimelle [18, s ] Komentopooli Vulkanissa komentopuskureita ei luoda itsessään, vaan ne luodaan komentopoolien kautta, joiden tehtävä on hallita komentopuskureita ja niiden vaatimaa muistia. Komentopoolit ovat linkitettyjä tiettyyn komentojonoperheeseen ja niistä luotuja komentopuskureita voikin lähettää vain saman jonoperheen komentojonoihin. Ennen komentopuskureiden käyttöä tuleekin siis luoda komentopooli. VkCommandPool commandpool; VkCommandPoolCreateInfo commandpoolcreateinfo = {}; commandpoolcreateinfo.stype = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; commandpoolcreateinfo.queuefamilyindex = graphicsqueueindex; vkcreatecommandpool(device, &commandpoolcreateinfo, nullptr, &commandpool); Tässä määritetään komentopooli käyttämällä VkCommandPoolCreateInfo-oliota ja annetaan sille aiemmin määritetty grafiikkakomentoja tukeva jonoperhe. Tämän jälkeen komentopooli luodaan käyttämällä funktiota vkcreatecommandpool [15.] Komentopooli tulee manuaalisesti tuhota käyttämällä vkdestroycommandpoolfunktiota [14].
36 Komentopuskurit Komentopuskurit ovat avain työn lähettämiseksi näytönohjaimelle, ja niiden avulla tapahtuu esimerkiksi kuvien piirtäminen. Komentopuskuri luodaan varaamalla se komentopoolista [18, s ]. VkCommandBufferAllocateInfo commandbufferallocateinfo = {}; commandbufferallocateinfo.stype = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; commandbufferallocateinfo.commandpool = commandpool; commandbufferallocateinfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; commandbufferallocateinfo.commandbuffercount = 1; vkallocatecommandbuffers(device, &commandbufferallocateinfo, &commandbuffer); Tässä määritetään luotavaksi yksi komentopuskuri käyttämällä VkCommand- BufferAllocateInfo-oliota ja siihen asetetaan aiemmin luotu komentopooli [15]. Komentopuskurit lähetetään näytönohjaimelle käyttämällä vkqueuesubmitfunktiota, mutta tähän tutustutaan tarkemmin kuvan piirtämistä käsittelevässä osiossa [15]. Komentopuskureita ei tarvitse tuhota, koska komentopoolin tuhoaminen tuhoaa myös komentopuskurille varatun muistin. Komentopuskureita voidaan kuitenkin palauttaa komentopoolille käyttämällä vkfreecommandbuffers-funktiota. Komentopuskurit voidaan myös nollata, joko yksitellen käyttämällä vkresetcommandbufferfunktiota siinä tilanteessa, että komentopoolille on luomisvaiheessa määritetty VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT-arvo, tai kaikki komentopoolista varatut komentopuskurit voidaan nollata käyttämällä vkresetcommand- Pool-funktiota [15.] 4.6 Datan siirtäminen näytönohjaimelle Vulkanissa dataa siirretään näytönohjaimelle käyttämällä erilaisia puskureita. Puskureita luodaan ensimmäiseksi määrittämällä puskurien käyttötarkoitus ja tämän jälkeen varaamalla puskurin tarvitsema muisti näytönohjaimesta.
37 Verteksipuskurit Verteksipuskurilla tarkoitetaan puskuria, joka sisältää esimerkiksi 3D-mallien verteksidataa. Verteksipuskuri on normaali Vulkanin puskuri, mutta sen käyttämiseksi kuvien piirtämisessä tulee ensin määrittää, mitä dataa se sisältää. Tämä tapahtuu luomalla verteksidatan määritys [18, s ] struct Vertex { glm::vec3 position; glm::vec3 color; }; Aluksi täytyy määrittää mitä verteksi pitää sisällään. Tässä tapauksessa verteksidata sisältää sijainti vektorin ja vektorin, joka määrittelee verteksin värin. Tämän jälkeen voidaan määrittää verteksidatan sisältö Vulkanille. VkVertexInputBindingDescription vertexinputdescription = {}; vertexinputdescription.binding = 0; vertexinputdescription.stride = sizeof(vertex); vertexinputdescription.inputrate = VK_VERTEX_INPUT_RATE_VERTEX; std::vector<vkvertexinputattributedescription> attributedescriptions(2); attributedescriptions[0].binding = 0; attributedescriptions[0].location = 0; attributedescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; attributedescriptions[0].offset = offsetof(vertex, position); attributedescriptions[1].binding = 0; attributedescriptions[1].location = 1; attributedescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; attributedescriptions[1].offset = offsetof(vertex, color); Tässä määritetään aluksi verteksidatan koko käyttämällä VkVertexInputBinding- Description-oliota ja kuinka sitä tulisi lukea [14]. Tämän jälkeen määritetään, kuinka verteksidata liitetään varjostimeen (liite 1) käyttämällä VkVertexInput- AttributeDescription-oliota [14]. Tämän jälkeen verteksidatan määritys tulisi lisätä grafiikkaliukuhihnan luonnissa mainittuun verteksidatan määritykseen.
38 32 Ennen verteksipuskurin luomista määritetään esimerkki dataa, joka piirtää yhden kolmion. std::vector<vertex> vertices = { { { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f } }, { { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f } }, { { 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f } } }; Tämän jälkeen voidaan luoda varsinainen verteksipuskuri. VkBuffer vertexbuffer; VkBufferCreateInfo vertexbuffercreateinfo = {}; vertexbuffercreateinfo.stype = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; vertexbuffercreateinfo.size = sizeof(vertex) * vertices.size(); vertexbuffercreateinfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; vkcreatebuffer(device, &vertexbuffercreateinfo, nullptr, &vertexbuffer); Tässä määritetään puskuri käyttämällä VkBufferCreateInfo-oliota ja siihen asetetaan verteksidatan koko, sekä määritetään puskurin käyttötavaksi verteksipuskuri [14]. Tämän jälkeen tulee selvittää, kuinka paljon muistia puskuri tarvitsee. VkMemoryRequirements memoryrequirements; vkgetbuffermemoryrequirements(device, vertexbuffer, &memoryrequirements); Tässä puskurin vaatima muistin määrä selvitetään käyttämällä vkgetbuffermemoryrequirements-funktiota ja tallennetaan VkMemoryRequirements-olioon. Tämän jälkeen voidaan varata puskurin tarvitsema muisti. VkPhysicalDeviceMemoryProperties memoryproperties; vkgetphysicaldevicememoryproperties(gpu, &memoryproperties); VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; uint32_t memorytype = 0; for (uint32_t i = 0; i < memoryproperties.memorytypecount; i++) { if (memoryrequirements.memorytypebits & 1 << i
39 33 && (memoryproperties.memorytypes[i].propertyflags & properties) == properties) { memorytype = i; break; } } VkMemoryAllocateInfo memoryallocateinfo = {}; memoryallocateinfo.stype = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memoryallocateinfo.allocationsize = memoryrequirements.size; memoryallocateinfo.memorytypeindex = memorytype; VkDeviceMemory memory; vkallocatememory(device, &memoryallocateinfo, nullptr, &memory); Tässä aluksi selvitetään, minkä tyyppiseen muistiin puskuri voidaan varata käyttämällä VkPhysicalDeviceMemoryProperties-oliota ja vkgetphysicaldevicememoryproperties-funktiota. Tämän jälkeen varataan muistia VkDeviceMemorykahvaan käyttämällä VkMemoryAllocateInfo-oliota ja vkallocatememory-funktiota [15.] Lopuksi verteksidata voidaan siirtää puskuriin. void* data; vkmapmemory(vulkan.device, memory, 0, memoryallocateinfo.allocationsize, 0, &data); memcpy(data, vertices.data(), verticessize); vkunmapmemory(vulkan.device, memory); Tässä muisti liitetään pointteriin käyttämällä vkmapmemory-funktiota, jonka avulla verteksidata kopioidaan puskuriin, ja lopuksi puskurin liitos vapautetaan käyttämällä vkunmapmemory-funktiota [14]. Tämän jälkeen verteksipuskuri on valmis käytettäväksi piirtämisessä. Verteksipuskuri tulee tuhota manuaalisesti käyttämällä vkdestroybufferfunktiota, ja verteksipuskurille varattu muisti tulee vapauttaa manuaalisesti käyttämällä vkfreememory-funktiota [15].
40 Indeksipuskurit Indeksipuskurilla tarkoitetaan puskuria, joka sisältää piirtämisessä käytettävää indeksidataa. Indeksidata mahdollistaa saman verteksin käyttämisen useassa kohdassa määrittämällä listan verteksien järjestysluvuista, joka määrittää missä järjestyksessä verteksit piirretään [18, s ] Indeksipuskurin luomiseksi määritetään ensin esimerkkidataa. std::vector<uint32_t> indices = { 0, 1, 2 }; Tässä määritetään indeksit yksinkertaisen kolmion piirtämiseksi. Tässä voidaan huomioida, että yksittäisen kolmion piirtämiseksi ei ole mitään käytännöllistä hyötyä indeksipuskurista, mutta esimerkiksi 3D-mallin piirtäminen hyötyisi tästä huomattavasti. Indeksipuskuri luodaan melkein samalla tavalla, kuin aiemmin mainittu verteksipuskuri. Erona on, että indeksipuskurin sisällöstä ei tarvitse tehdä määritelmää Vulkanille, ja puskuria luodessa käytetään VK_BUFFER_USAGE_INDEX_BUFFER_BITarvoa. Kuten verteksipuskuri myös indeksipuskuri ja sille varattu muisti tulee tuhota manuaalisesti. 4.7 Kuvan piirtäminen Vulkanissa kuvan piirtäminen tarkoittaa vaihtoketjun kuvaan grafiikan piirtämistä ja sen näyttämistä käyttäjälle. Kuvan piirtämiseksi tuleekin siis pyytää vaihtoketjulta käytettävä kuva, ja sen jälkeen komentopuskureiden avulla käyttää sitä piirtämiseen. Kuvan piirtämisen vaiheet tulee myös manuaalisesti synkronoida, jotta kuvaan ei esimerkiksi piirretä ennen kuin se on käytettävissä.
41 Semaforit Vulkanissa piirtämisen synkronointiin voidaan käyttää esimerkiksi semaforeja [18, s ]. Semaforien luominen on hyvin yksinkertaista ja se tapahtuu seuraavasti. VkSemaphore imageavailable; VkSemaphoreCreateInfo semaphorecreateinfo = {}; semaphorecreateinfo.stype = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; vkcreatesemaphore(device, &semaphorecreateinfo, nullptr, &imageavailable); Tässä luodaan semafori käyttämällä VkSemaphoreCreateInfo-oliota, johon ei tarvitse määrittää mitään arvoja, ja vkcreatesemaphore-funktiota. Synkronoinnin toteuttamiseksi semaforeilla tulisi myös luoda toinen semafori kuvan piirtämisen loppua varten, jotta tiedetään, milloin kuva on valmis näytettäväksi käyttäjälle. Tähän semaforiin viitataan myöhemmin nimellä rendercomplete Komentopuskurin täyttäminen Ennen piirtämistä tulee kaikki piirtämisessä vaaditut komennot lisätä komentopuskuriin. Tässä esimerkissä komentopuskuri ei koskaan muutu, joten kaikki tarvittavat komennot voidaan lisätä yhdellä kertaa, ja uudelleen käyttää täytettyä komentopuskuria jokaisen kuvan piirtämiseksi. Seuraavissa koodiesimerkeissä oletetaan, että kaikilla vaihtoketjun kuvilla on myös oma komentopuskuri ja koodi tapahtuu silmukan sisällä. Komentojen lisäämiseksi täytyy ensin komentopuskurille kertoa, että komentoja aletaan syöttää. VkCommandBufferBeginInfo commandbufferbegininfo = {}; commandbufferbegininfo.stype = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; vkbegincommandbuffer(swapchainbuffers[i].commandbuffer,
42 36 &commandbufferbegininfo); Tässä komentopuskurille kerrotaan komentojen syöttämisen alkamisesta käyttämällä VkCommandBufferBeginInfo-oliota ja vkbegincommandbuffer-funktiota [14]. Seuraavaksi tulee määrittää piirtokierroksen alku. VkClearValue clearvalue; clearvalue.color = {0.0f, 0.0f, 0.0f, 1.0f}; VkRenderPassBeginInfo renderpassbegininfo = {}; renderpassbegininfo.stype = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderpassbegininfo.renderpass = renderpass; renderpassbegininfo.renderarea.offset.x = 0; renderpassbegininfo.renderarea.offset.y = 0; renderpassbegininfo.renderarea.extent.width = windowwidth; renderpassbegininfo.renderarea.extent.height = windowheight; renderpassbegininfo.clearvaluecount = 1; renderpassbegininfo.pclearvalues = &clearvalue; renderpassbegininfo.framebuffer = framebuffers[i]; vkcmdbeginrenderpass(swapchainbuffers[i].commandbuffer, &renderpassbegininfo, VK_SUBPASS_CONTENTS_INLINE); Tässä määritetään VkRenderPassBeginInfo-olio, johon asetetaan piirtokierros, ikkunan koko, kuvapuskurit ja kuvan tyhjentämisen väri. Tämän jälkeen piirtokierros aloitetaan vkcmdbeginrenderpass-funktiolla [15.] Tämän jälkeen komentopuskuriin voidaan syöttää piirtokomentoja ja ensimmäiseksi määritetään aiemmin dynaamiseksi tilaksi määritetty kuvaportin koko. VkViewport viewport = {}; viewport.height = static_cast<float>(windowheight); viewport.width = static_cast<float>(windowwidth); viewport.mindepth = 0.0f; viewport.maxdepth = 1.0f; vkcmdsetviewport(swapchainbuffers[i].commandbuffer, 0, 1, &viewport); VkRect2D scissor = {}; scissor.extent.width = windowwidth; scissor.extent.height = windowheight; scissor.offset.x = 0; scissor.offset.y = 0; vkcmdsetscissor(swapchainbuffers[i].commandbuffer, 0, 1, &scissor); Tässä määritetään kuvaportin koko käyttämällä VkViewport- ja VkRect2D-oliota sekä käyttämällä vkcmdsetviewport- ja vkcmdsetscissor-funktiota [14].
43 37 Seuraavaksi tulee määrittää, mitä grafiikkaliukuhihnaa komentopuskuri käyttää. vkcmdbindpipeline(swapchainbuffers[i].commandbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); Tässä grafiikkaliukuhihna määritetään käyttöön funktiolla vkcmdbindpipeline [15]. Seuraavaksi voidaan liittää verteksi- ja indeksipuskuri sekä lisätä komentopuskuriin piirtämiskomento. VkDeviceSize offsets[1] = { 0 }; vkcmdbindvertexbuffers(swapchainbuffers[i].commandbuffer, 0, 1, &vertexbuffer, offsets); vkcmdbindindexbuffer(vulkan.swapchainbuffers[i].commandbuffer, indexbuffer, 0, VK_INDEX_TYPE_UINT32); vkcmddrawindexed(swapchainbuffers[i].commandbuffer, indices.size(), 1, 0, 0, 1); Tässä käytettävä verteksipuskuri määritetään funktiolla vkcmdbindvertexbuffers ja käytettävä indeksipuskuri funktiolla vkcmdbindindexbuffer. Tämän jälkeen komentopuskuriin lisätään indeksipuskuria käyttävä piirtokomento käyttämällä funktiota vkcmddrawindexed, mikä piirtää kuvan komentopuskuriin määritetyillä tiedoilla [14.] Lopuksi lopetetaan piirtokierros ja komentopuskuriin komentojen lisäämisen. vkcmdendrenderpass(swapchainbuffers[i].commandbuffer); vkendcommandbuffer(swapchainbuffers[i].commandbuffer); Tässä piirtokierros lopetetaan vkcmdendrenderpass-funktiolla ja komentojen lisääminen komentopuskuriin vkendcommandbuffer-funktiolla [14] Kuvan esittäminen Kun komentopuskuri on täytetty halutuilla komennoilla, voidaan se lähettää komentojonolle. Tämän jälkeen kuva esiteetään ikkunassa. Ennen kuin komentoja voidaan lähettää eteenpäin, tulee varmistaa, että laite on valmis ja pyytää vaihtoketjulta kuva.
44 38 vkdevicewaitidle(device); uint32_t currentbuffer; vkacquirenextimagekhr(device, vulkan.swapchain, std::numeric_limits<uint64_t>::max(),semaphores.imageavailable, VK_NULL_HANDLE, ¤tbuffer); Tässä odotetaan ensin, että laite on valmis piirtämään käyttämällä vkdevicewaitidle-funktiota. Tämän jälkeen pyydetään vaihtoketjulta seuraavaa kuvaa käyttämällä vkacquirenextimagekhr-funktiota [14.] Seuraavaksi voidaan lähettää komentopuskuri komentojonolle. VkPipelineStageFlags pipelinestages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkSubmitInfo submitinfo = {}; submitinfo.stype = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitinfo.pwaitdststagemask = &pipelinestages; submitinfo.waitsemaphorecount = 1; submitinfo.pwaitsemaphores = &imageavailable; submitinfo.commandbuffercount = 1; submitinfo.pcommandbuffers = &swapchainbuffers[currentbuffer].commandbuffer; submitinfo.signalsemaphorecount = 1; submitinfo.psignalsemaphores = &rendercomplete; vkqueuesubmit(queue, 1, &submitinfo, VK_NULL_HANDLE); Tässä määritetään VkSubmitInfo-olio, johon asetetaan lähettävät komentopuskurit ja synkronoimiseen käytettävät semaforit. Tämän jälkeen komentopuskuri lähetetään komentojonolle käyttämällä vkqueuesubmit-funktiota [15.] Lopuksi kuva voidaan näyttää ikkunassa. VkPresentInfoKHR presentinfo = {}; presentinfo.stype = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentinfo.swapchaincount = 1; presentinfo.pswapchains = &swapchain; presentinfo.pimageindices = ¤tbuffer; presentinfo.waitsemaphorecount = 1; presentinfo.pwaitsemaphores = &rendercomplete; vkqueuepresentkhr(queue, &presentinfo);
45 39 Tässä määritetään VkPresentInfoKHR-olio, johon asetetaan käytettävä vaihtoketju ja vaihtoketjun näytettävä kuva sekä synkronoinnissa käytettävä semafori. Lopuksi kuva esitetään ikkunassa käyttämällä vkqueuepresentkhr-funktiota (kuva 7) [14.] Kuva 7. Esimerkkiohjelman piirtämä kolmio.
Jypelin käyttöohjeet» Ruutukentän luominen
Jypelin käyttöohjeet» Ruutukentän luominen Pelissä kentän (Level) voi luoda tekstitiedostoon "piirretyn" mallin mukaisesti. Tällöin puhutaan, että tehdään ns. ruutukenttä, sillä tekstitiedostossa jokainen
Ohjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat
ELM GROUP 04. Teemu Laakso Henrik Talarmo
ELM GROUP 04 Teemu Laakso Henrik Talarmo 23. marraskuuta 2017 Sisältö 1 Johdanto 1 2 Ominaisuuksia 2 2.1 Muuttujat ja tietorakenteet...................... 2 2.2 Funktiot................................
Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo
Concurrency - Rinnakkaisuus Group: 9 Joni Laine Juho Vähätalo Sisällysluettelo 1. Johdanto... 3 2. C++ thread... 4 3. Python multiprocessing... 6 4. Java ExecutorService... 8 5. Yhteenveto... 9 6. Lähteet...
Ohjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 7.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 7.2.2011 1 / 39 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti
CUDA. Moniydinohjelmointi 17.4.2012 Mikko Honkonen
CUDA Moniydinohjelmointi 17.4.2012 Mikko Honkonen Yleisesti Compute Unified Device Architecture Ideana GPGPU eli grafiikkaprosessorin käyttö yleiseen laskentaan. Nvidian täysin suljetusti kehittämä. Vuoden
Videokuvan siirtäminen kamerasta tietokoneelle Windows Movie Maker -ohjelman avulla
Videokuvan siirtäminen kamerasta tietokoneelle Windows Movie Maker -ohjelman avulla 1. Digivideokamera liitetään tietokoneeseen FireWire-piuhalla. (Liitännällä on useita eri nimiä: myös IEEE 1394, DV,
Action Request System
Action Request System Manu Karjalainen Ohjelmistotuotantovälineet seminaari HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos 25.10.2000 Action Request System (ARS) Manu Karjalainen Ohjelmistotuotantovälineet
IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit
IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,
ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014
18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,
MPCC-työkalua voidaan käyttää yhden laitteen valvontaan ja yhden tai useamman laitteen konfigurointiin (Modbus broadcast, osoite 0).
V1.0.0 (14.10.2015) 1 (7) KYTKENTÄ HUOM: toimii Modbus-masterina. Tämän vuoksi toinen mahdollinen Modbus-master on irrotettava verkosta, kun kytketään valmiiseen Modbus-verkkoon. Produalin Modbus-laitteiden
UpdateIT 2010: Editorin käyttöohje
UpdateIT 2010: Editorin käyttöohje Käyttäjätuki: Suomen Golfpiste Oy Esterinportti 1 00240 HELSINKI Puhelin: (09) 1566 8800 Fax: (09) 1566 8801 E-mail: gp@golfpiste.com Sisällys Editorin käyttöohje...
Harjoitustyö: virtuaalikone
Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman
Kieliversiointityökalu Java-ohjelmistoon. Ohje
Kieliversiointityökalu Java-ohjelmistoon Ohje 2/6 SISÄLLYSLUETTELO 1 YLEISTÄ OHJELMASTA... 3 2 PÄÄ-IKKUNA...4 3 YLÄVALIKKO... 4 3.1 TIEDOSTO... 4 3.2 TOIMINTO... 4 3.3 ASETUKSET... 5 3.4 OHJE... 5 4 VÄLILEHDET...5
TeleWell TW-LTE/4G/3G USB -modeemi Cat 4 150/50 Mbps
TeleWell TW-LTE/4G/3G USB -modeemi Cat 4 150/50 Mbps Pikaohje Laite toimii Windows XP SP3, Windows 7,8,10 ja Mac OSx 10.5 tai käyttöjärjestelmissä, Linux tuki netistä ladattavilla ajureilla USB portin
DXL Library ja DXL-kielen olemus. Pekka Mäkinen Pekka.Makinen@softqa.fi SoftQA Oy http/www.softqa.fi/
DXL Library ja DXL-kielen olemus Pekka Mäkinen Pekka.Makinen@softqa.fi SoftQA Oy http/www.softqa.fi/ DOORS extension Language DXL on DOORSin laajennuskieli, jolla voidaan kehittää lisätoiminnallisuutta.
Maventa Connector Käyttöohje
Maventa Connector Käyttöohje 17.4.2015 Sisällys 1. Esittely... 2 1.1. Käytön edellytykset... 2 1.2. Tuetut aineistomuodot... 2 2. Asennustiedosto... 3 2.1. Sisäänkirjautuminen... 7 3. Asetuksien määrittäminen...
Javan asennus ja ohjeita ongelmatilanteisiin
Javan asennus ja ohjeita ongelmatilanteisiin Javaa tarvitaan Fivaldin Sovellusikkunan alaisiin sovelluksiin, jotka käyttävät Oracle Forms -tekniikkaa. Visma Fivaldin osalta suosittelemme aina käyttämään
Pedacode Pikaopas. Java-kehitysympäristön pystyttäminen
Pedacode Pikaopas Java-kehitysympäristön pystyttäminen Pikaoppaan sisältö Pikaoppaassa kuvataan, miten Windowstyöasemalle asennetaan Java-ohjelmoinnissa tarvittavat työkalut, minkälaisia konfigurointeja
Loppuraportti. Virtuaali-Frami, CAVE-ohjelmisto. Harri Mähönen projektiassistentti Seinäjoen ammattikorkeakoulu. Versio
1 Loppuraportti Virtuaali-Frami, CAVE-ohjelmisto Harri Mähönen projektiassistentti Seinäjoen ammattikorkeakoulu Versio 1.0 15.1.2006 2 Sisällys Tiivistelmä... 3 1 Johdanto... 4 1.1 Dokumentin tarkoitus...
Valintanauhan komennot Valintanauhan kussakin välilehdessä on ryhmiä ja kussakin ryhmässä on toisiinsa liittyviä komentoja.
Pikaopas Microsoft Excel 2013 näyttää erilaiselta kuin aiemmat versiot. Tämän oppaan avulla pääset alkuun nopeasti ja saat yleiskuvan uusista ominaisuuksista. Komentojen lisääminen pikatyökaluriville Pidä
Mainosankkuri.fi-palvelun käyttöohjeita
Mainosankkuri.fi-palvelun käyttöohjeita Sisällys 1. Johdanto... 1 2. Sisäänkirjautuminen... 1 3. Palvelussa navigointi... 2 4. Laitteet... 2 5. Sisällönhallinta... 4 6. Soittolistat... 7 7. Aikataulut...
EKP:N HANKINTAMENETTELYJEN VERKKOPALVELU OSALLISTUMINEN HANKINTAMENETTELYIHIN
Taloushallinnon pääosasto ECB-UNRESTRICTED 8.11.2016 EKP:N HANKINTAMENETTELYJEN VERKKOPALVELU OSALLISTUMINEN HANKINTAMENETTELYIHIN Seuraavassa esitetään ohjeet pyydettyjen tietojen toimittamiseen EKP:n
2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)
2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi
Ulkoiset mediakortit Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2007 Hewlett-Packard Development Company, L.P. SD-logo on omistajansa tavaramerkki. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. Tässä olevat tiedot
Ohjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print
Opiskelun ja työelämän tietotekniikka (DTEK1043)
Opiskelun ja työelämän tietotekniikka (DTEK1043) pääaine- ja sivuaineopiskelijat Taulukkolaskennan perusteet Yleistä Tämä harjoitus käsittelee taulukkolaskentaohjelman perustoimintoja. Harjoituksissa opetellaan
PRINTER DRIVER PÄÄKÄYTTÄJÄN OPAS
PÄÄKÄYTTÄJÄN OPAS OpusCapita pidättää oikeuden muuttaa tuotteen ominaisuuksia ja tätä tuotekuvausta. Uusimmat versiot julkaistaan osoitteessa www.opuscapita.com/terms. 1. TEHTÄVÄKUVAUS Pääkäyttäjällä on
Tietorakenteet ja algoritmit
Tietorakenteet ja algoritmit Merkintöjen tulkintoja *++Pstack->top = item *Pstack->top++ = item (*Pstack->top)++ *(Pstack++)->top = item *(++Pstack)->top = item Lisää pinon toteutuksia Dynaaminen taulukko
Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.
Tehtävä 63. Kirjoita oma versio funktiosta strcmp(),joka saa parametrinaan kaksi merkkiosoitinta. Tee ohjelma, jossa luetaan kaksi merkkijonoa, joita sitten verrataan ko. funktiolla. Tehtävä 64. Kirjoita
Ulkoiset mediakortit Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2007 Hewlett-Packard Development Company, L.P. SD-logo on omistajansa tavaramerkki. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. Tässä olevat tiedot
Monikielinen verkkokauppa
Monikielinen verkkokauppa Monikielinen verkkokauppa Monikielisen verkkokaupan luomisessa pitää Multiple Languages lisämoduuli olla aktivoituna. Klikkaa valikosta Features -> Apps Management -> näkyviin
Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla
Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla ALKUHARJOITUS Kynän ja paperin avulla peilaaminen koordinaatistossa a) Peilaa pisteen (0,0) suhteen koordinaatistossa sijaitseva - neliö, jonka
Fiery Driver Configurator
2015 Electronics For Imaging, Inc. Tämän julkaisun tiedot kuuluvat tämän tuotteen Lakisääteisien ilmoitusten piiriin. 16. marraskuuta 2015 Sisällys 3 Sisällys Fiery Driver Configurator...5 Järjestelmävaatimukset...5
Sukupuu -ohjelma. Ossi Väre (013759021) Joni Virtanen (013760641)
Sukupuu -ohjelma Ossi Väre (013759021) Joni Virtanen (013760641) 7.11.2011 1 Johdanto Toteutimme C -kielellä sukupuuohjelman, johon käyttäjä voi lisätä ja poistaa henkilöitä ja määrittää henkilöiden välisiä
Käyttöohje. Ticket Inspector. Versio 1.0. Sportum Oy
Käyttöohje Ticket Inspector Versio 1.0 Sportum Oy 10.5.2017 Sivu 1 Sisällysluettelo 1. Yleistä... 2 2. Kirjautuminen ensimmäisellä kerralla / PIN-koodin unohtuessa... 3 3. Tunnistautuminen... 4 4. Päänäkymä...
TIES471 Reaaliaikainen renderöinti
TIES471 Reaaliaikainen renderöinti Kotitehtävä 2.3.3 Muistin kaistanleveys Koko kaistanleveyden kustannus: B = d * Zr + o(d) * (Z w + C w + T r ) Lisätään vielä tekstuuri välimuisti (texture cache) vaikutus
Interfacing Product Data Management System
Interfacing Product Data Management System Tekijä: Työn valvoja: Mats Kuivalainen Timo Korhonen Esitelmän sisältö Työn suorituspaikka - Ideal Product Data Oy Käsitteitä Työn tavoitteet Työn tulokset 1/5
OptimePortal ja OptimeEvent versioiden yhteenveto joulukuu
OptimePortal 1.12.2 ja OptimeEvent 1.16.1 versioiden yhteenveto joulukuu 2016 www.helsinki.fi/yliopisto 1 Tilavaraus Tilavarauspyyntöä luotaessa laskutusyksikkö (ns. H-koodi) voidaan nyt valita viimeisessä
OHJE Jos Kelaimeen kirjautuminen ei onnistu Mac-koneella Sisällys
Sisällys 1 Varmista, että DigiSign-kortinlukijaohjelmisto on käynnissä 2 1.1 DigiSign-kuvake 2 1.2 Sovelluksen käynnistäminen 2 1.3 Kortin toiminnan varmistaminen 4 2 Jos käytät selaimena Mozilla, Firefox
Luku 6: Grafiikka. 2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat
2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat 2D-piirto 2-ulotteisen grafiikan piirto perustuu yleensä valmiiden kuvien kopioimiseen näyttömuistiin (blitting)
Ulkoiset mediakortit. Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2007 Hewlett-Packard Development Company, L.P. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. Tässä olevat tiedot voivat muuttua ilman ennakkoilmoitusta.
Sonera Viestintäpalvelu VIP VIP Laajennettu raportointi Ohje
Sonera Viestintäpalvelu VIP VIP Laajennettu raportointi Ohje Sisällysluettelo VIP Laajennettu raportointi... 3 Luo raportti Laajennetun raportoinnin työkaluilla... 4 Avaa Laajennettu raportointi... 4 Valitse
Osallistavan suunnittelun kyselytyökalu
Osallistavan suunnittelun kyselytyökalu Käyttöohje InnoGIS- hankkeen aikana kehitetylle pilottiversiolle Dokumentti sisältää pilottiversiona toimivan kyselyn laatimiseen ja vastaamiseen liittyvän ohjeistuksen.
Nspire CAS - koulutus Ohjelmiston käytön alkeet Pekka Vienonen
Nspire CAS - koulutus Ohjelmiston käytön alkeet 3.12.2014 Pekka Vienonen Ohjelman käynnistys ja käyttöympäristö Käynnistyksen yhteydessä Tervetuloa-ikkunassa on mahdollisuus valita suoraan uudessa asiakirjassa
Ohjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 8.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 8.2.2010 1 / 38 Debuggeri Tyypillinen tilanne: ohjelma on kirjoitettu, Python-tulkki ei valita virheistä, mutta ohjelma
Ulkoiset mediakortit Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2008 Hewlett-Packard Development Company, L.P. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. SD-logo on omistajansa tavaramerkki. Tuotetta koskeva
Sisältö. 22. Taulukot. Yleistä. Yleistä
Sisältö 22. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko metodin parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 22.1 22.2 Yleistä
Ohjelmointikielet ja -paradigmat 5op. Markus Norrena
Ohjelmointikielet ja -paradigmat 5op Markus Norrena Ko#tehtävä 4 Viimeistele "alkeellinen kuvagalleria". Käytännössä kaksi sivua Yksi jolla voi ladata kuvia palvelimelle (file upload) Toinen jolla ladattuja
Videon tallentaminen Virtual Mapista
Videon tallentaminen Virtual Mapista Kamera-ajon tekeminen Karkean kamera ajon teko onnistuu nopeammin Katseluohjelmassa (Navigointi > Näkymät > Tallenna polku). Liikeradan ja nopeuden tarkka hallinta
CODEONLINE. Monni Oo- ja Java-harjoituksia. Version 1.0
CODEONLINE Monni Oo- ja Java-harjoituksia Version 1.0 Revision History Date Version Description Author 25.10.2000 1.0 Initial version Juha Johansson Inspection History Date Version Inspectors Approved
Ohjelmoinnin peruskurssi Y1
Ohjelmoinnin peruskurssi Y1 CSE-A1111 28.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 28.9.2015 1 / 16 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.
.NET ajoympäristö. Juha Järvensivu 2007
.NET ajoympäristö Juha Järvensivu juha.jarvensivu@tut.fi 2007 Käännösprosessi C# lähdekoodi C# kääntäjä CILtavukoodi JITkäännös Ajettava natiivikoodi Kehitysympäristössä ohjelmoijan toimesta Ajonaikana.NET
FinFamily PostgreSQL installation ( ) FinFamily PostgreSQL
FinFamily PostgreSQL 1 Sisällys / Contents FinFamily PostgreSQL... 1 1. Asenna PostgreSQL tietokanta / Install PostgreSQL database... 3 1.1. PostgreSQL tietokannasta / About the PostgreSQL database...
Yhteydensaantiongelmien ja muiden ongelmien ratkaisuita
Yhteydensaantiongelmien ja muiden ongelmien ratkaisuita Miksi SmartView v4.1 ei suostu avaamaan lämpökuvia? Mikäli SmartView-ohjelmiston täysversio 4.1 ladataan suoraan nettisivuilta, jotkin tietokoneet
Ulkoiset mediakortit Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2009 Hewlett-Packard Development Company, L.P. Java on Sun Microsystems, Inc:in yhdysvaltalainen tavaramerkki. SD-logo on omistajansa tavaramerkki. Tuotetta koskeva
Ulkoiset mediakortit. Käyttöohje
Ulkoiset mediakortit Käyttöohje Copyright 2007 Hewlett-Packard Development Company, L.P. SD-logo on omistajansa tavaramerkki. Tässä olevat tiedot voivat muuttua ilman ennakkoilmoitusta. Ainoat HP:n tuotteita
Selainpelien pelimoottorit
Selainpelien pelimoottorit Teemu Salminen Helsinki 28.10.2017 Seminaaritutkielma Helsingin yliopisto Tietojenkäsittelytiede ! 1 HELSINGIN YLIOPISTO HELSINGFORS UNIVERSITET UNIVERSITY OF HELSINKI Tiedekunta
Dart. Ryhmä 38. Ville Tahvanainen. Juha Häkli
Dart Ryhmä 38 Ville Tahvanainen Juha Häkli 1.LYHYESTI Dart on luokkapohjainen, yksiperintäinen, puhdas olio-ohjelmointikieli. Dart on dynaamisesti tyypitetty. Sovellukset on organisoitu modulaarisiksi
Tilastolliset ohjelmistot 805340A. Pinja Pikkuhookana
Tilastolliset ohjelmistot 805340A Pinja Pikkuhookana Sisältö 1 SPSS 1.1 Yleistä 1.2 Aineiston syöttäminen 1.3 Aineistoon tutustuminen 1.4 Kuvien piirtäminen 1.5 Kuvien muokkaaminen 1.6 Aineistojen muokkaaminen
GeoGebra-harjoituksia malu-opettajille
GeoGebra-harjoituksia malu-opettajille 1. Ohjelman kielen vaihtaminen Mikäli ohjelma ei syystä tai toisesta avaudu toivomallasi kielellä, voit vaihtaa ohjelman käyttöliittymän kielen seuraavasti: 2. Fonttikoon
ASCII-taidetta. Intro: Python
Python 1 ASCII-taidetta All Code Clubs must be registered. Registered clubs appear on the map at codeclubworld.org - if your club is not on the map then visit jumpto.cc/18cplpy to find out what to do.
Oppilaan pikaopas. Project 2013 käyttöliittymä ja näkymät
1 Oppilaan pikaopas Project 2013 käyttöliittymä ja näkymät Kun avaat Project 2013 -ohjelman, näet ensimmäisenä pelkistetyn näkymän. Uusi Project 2013 voi auttaa projektinhallinnassa kuten esim. projektitietojen
Visma Business AddOn Tositteiden tuonti. Käsikirja
Visma Business AddOn Tositteiden tuonti Käsikirja Oppaan päiväys: 10.2.2012. Asiakaspalvelu: Helpdesk: www.visma.fi Visma Software Oy pidättää itsellään oikeuden mahdollisiin parannuksiin ja/tai muutoksiin
Maastotietokannan torrent-jakelun shapefile-tiedostojen purkaminen zip-arkistoista Windows-komentojonoilla
Maastotietokannan torrent-jakelun shapefile-tiedostojen purkaminen zip-arkistoista Windows-komentojonoilla Viimeksi muokattu 5. toukokuuta 2012 Maastotietokannan torrent-jakeluun sisältyy yli 5000 zip-arkistoa,
Luku 7 Uusien Mallien Tiedostot
Luku 7 Uusien Mallien Tiedostot Kaikki ZoomTextin asetukset voidaan tallentaa ja palauttaa käyttämällä mallitiedostoja. Mallitiedostot kontrolloivat kaikkia ZoomTextin toimintoja mukaan lukien suurennustasot,
Käyttäjän käsikirja. LIB 500 ja LIB 510 v.4.0.2. 8.2. Releasettelutyökalu. 8.2.1. Yleistä. ,NNXQDMRNDLOPRLWWDDHWWlNRKGHRQSlLYLWHWWlYl
1MRS751368-RUM Käyttäjän käsikirja 8.1. Releyksikön valitseminen Releyksiköt esitetään asemakuvassa painikkeina. 8 $VHPDNXYDMRVVDQlN\\UHOH\NVLNN Jos kohteita tarvitsee päivittää, avataan ikkuna (Kuva 8.1.-2)
1. Adobe Digital Editions ohjelman käyttöönotto
1. Adobe Digital Editions ohjelman käyttöönotto Useimmat verkkokaupassa myytävät e-kirjat on suojattu Adobe DRM suojauksella. Näitä e-kirjoja voi lukea vain Adobe Digital Editions ohjelmalla, joka on asennettava
SoleMOVE lähtevän harjoittelijan ohje
SoleMOVE lähtevän harjoittelijan ohje 3.12.2013 Kuva: Sanna Waris SoleMOVE lähtevän ERASMUS- harjoittelijan ohje 1 SoleMOVE lähtevän harjoittelijan ohje... 1 1. Kirjautuminen... 3 2. Uuden lähtevän Erasmus-harjoittelijan
Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä
Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,
Enigmail-opas. Asennus. Avainten hallinta. Avainparin luominen
Enigmail-opas Enigmail on Mozilla Thunderbird ja Mozilla Seamonkey -ohjelmille tehty liitännäinen GPG-salausohjelmiston käyttöä varten. Sitä käytetään etenkin Thunderbirdin kanssa sähköpostin salaamiseen
Ulkoiset mediakortit. Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2006 Hewlett-Packard Development Company, L.P. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. Tässä olevat tiedot voivat muuttua ilman ennakkoilmoitusta.
Avaa ohjelma ja tarvittaessa Tiedosto -> Uusi kilpailutiedosto
Condess ratamestariohjelman käyttö Aloitus ja alkumäärittelyt Avaa ohjelma ja tarvittaessa Tiedosto -> Uusi kilpailutiedosto Kun kysytään kilpailun nimeä, syötä kuvaava nimi. Samaa nimeä käytetään oletuksena
Ohjelmoinnin peruskurssi Y1
Ohjelmoinnin peruskurssi Y1 CS-A1111 10.10.2018 CS-A1111 Ohjelmoinnin peruskurssi Y1 10.10.2018 1 / 20 Oppimistavoitteet: tämän luennon jälkeen Tiedät, miten ohjelman toimintaa voi tutkia ja ohjelmassa
Varmuuskopiointi ja palauttaminen Käyttöopas
Varmuuskopiointi ja palauttaminen Käyttöopas Copyright 2008 Hewlett-Packard Development Company, L.P. Windows on Microsoft Corporationin Yhdysvalloissa rekisteröimä tavaramerkki. Tässä olevat tiedot voivat
Ulkoiset mediakortit Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2010 Hewlett-Packard Development Company, L.P. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. SD-logo on omistajansa tavaramerkki. Tuotetta koskeva
Android ohjelmointi. Mobiiliohjelmointi 2-3T5245
Android ohjelmointi Mobiiliohjelmointi 2-3T5245 Mikä on Android? Linux kernelin päälle rakennettu, Googlen kehittämä sovelluspino mobiilisovelluksiin Erillinen versio puhelimelle ja taulutietokoneille
TIETOKONE JA TIETOVERKOT TYÖVÄLINEENÄ
aaro.leikari@hotmail.com TIETOKONE JA TIETOVERKOT TYÖVÄLINEENÄ 25.01.2016 SISÄLLYS 1. Käyttöjärjestelmän asentaminen... 1 1.1 Windowsin asettamia laitteistovaatimuksia... 1 1.2 Windowsin asentaminen...
Kon Konepajojen tuotannonohjaus: ILOG CPLEX Studion käyttö
Kon-15.4199 Konepajojen tuotannonohjaus: ILOG CPLEX Studion käyttö 22.1.2016 Harjoituksessa 1. Varmistetaan että kaikilla on pari! Ilmoittautukaa oodissa etukäteen! 2. Tutustutaan ensimmäiseen tehtävään
JWT 2016 luento 11. to 21.4.2016 klo 14-15. Aulikki Hyrskykari. PinniB 1097. Aulikki Hyrskykari
JWT 2016 luento 11 to 21.4.2016 klo 14-15 Aulikki Hyrskykari PinniB 1097 1 Viime luennolla o AJAX ja JSON, harjoitustyön tehtävänanto, vierailuluento avoimesta datasta Tänään o APIt rajapinnoista yleisesti
UCOT-Sovellusprojekti. Asennusohje
UCOT-Sovellusprojekti Asennusohje Ilari Liukko Tuomo Pieniluoma Vesa Pikki Panu Suominen Versio: 1.00 Julkinen 15. joulukuuta 2006 Jyväskylän yliopisto Tietotekniikan laitos Jyväskylä Hyväksyjä Päivämäärä
Arkkitehtuurikuvaus. Ratkaisu ohjelmistotuotelinjan monikielisyyden hallintaan Innofactor Oy. Ryhmä 14
Arkkitehtuurikuvaus Ratkaisu ohjelmistotuotelinjan monikielisyyden hallintaan Innofactor Oy Ryhmä 14 Muutoshistoria Versio Pvm Päivittäjä Muutos 0.4 1.11.2007 Matti Eerola 0.3 18.10.2007 Matti Eerola 0.2
Ulkoiset mediakortit. Käyttöopas
Ulkoiset mediakortit Käyttöopas Copyright 2006 Hewlett-Packard Development Company, L.P. SD-logo on omistajansa tavaramerkki. Java on Sun Microsystems, Inc:n tavaramerkki Yhdysvalloissa. Tässä olevat tiedot
Taulukot. Jukka Harju, Jukka Juslin 2006 1
Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti
Kuvankäsittely. DigiReWork Annamari Mäenhovi Kati Nieminen
Kuvankäsittely DigiReWork 14.11.2017 Annamari Mäenhovi Kati Nieminen Työpajan sisältö Valokuvaamisen karkeat perusteet Kuvien ottamisen ja käyttämisen laillisuus Digitaalinen kuva Erityisvaatimukset alustoille
Keskustelualue. Tampereen yliopisto/ tietohallinto 2017 Suvi Junes/Pauliina Munter
Keskustelualue Keskustelualue soveltuu eriaikaisen viestinnän välineeksi. Keskustelualueelle voidaan lähettää viestejä toisten luettavaksi, ja sitä voidaan käyttää alueena myös ryhmätöiden tekemiseen,
Office 365 palvelujen käyttöohje Sisällys
Office 365 palvelujen käyttöohje Sisällys Sisäänkirjautuminen... 2 Office 365:n käyttöliittymä... 3 Salasanan vaihto... 5 Outlook-sähköpostin käyttö... 7 Outlook-kalenterin käyttö... 10 OneDriven käyttö...
Suvi Junes Tietohallinto / Opetusteknologiapalvelut 2012
Tiedostot Uudet ominaisuudet: - Ei Tiedostot-kohtaa alueen sisällä, vaan tiedostonvalitsin, jolla tiedostot tuodaan alueelle siihen kohtaan missä ne näytetään - Firefox-selaimella voi työpöydältä raahata
S11-09 Control System for an. Autonomous Household Robot Platform
S11-09 Control System for an Autonomous Household Robot Platform Projektisuunnitelma AS-0.3200 Automaatio- ja systeemitekniikan projektityöt Quang Doan Lauri T. Mäkelä 1 Kuvaus Projektin tavoitteena on
Varmuuskopiointi ja palauttaminen
Varmuuskopiointi ja palauttaminen Käyttöopas Copyright 2007 Hewlett-Packard Development Company, L.P. Windows on Microsoft Corporationin Yhdysvalloissa rekisteröimä tavaramerkki. Tässä olevat tiedot voivat
Rinnakkaisuuden hyväksikäyttö peleissä. Paula Kemppi
Rinnakkaisuuden hyväksikäyttö peleissä Paula Kemppi 24.4.2008 Esityksen rakenne Johdantoa Rinnakkaisuus Pelimoottorien rinnakkaisuuden mallit Funktionaalisen rinnakkaisuuden malli Rinnakkaisen tiedon malli
Visma Fivaldi -käsikirja Tehtävienhallinta- ohje käyttäjälle
Visma Fivaldi -käsikirja Tehtävienhallinta- ohje käyttäjälle 2 Sisällys 1 Palvelunhallinta... 3 1.1 Käyttäjäryhmän luominen... 3 2 Tehtävienhallinta- perustiedot... 4 2.1 Yhtiön perustiedot... 4 2.2 Tehtävä-/
Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia?
Muilla kielillä: English Suomi Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia? Kun kaksi fysiikkaoliota törmää toisiinsa, syntyy törmäystapahtuma. Nämä tapahtumat voidaan ottaa kiinni
KÄYTTÖOHJE. Servia. S solutions
KÄYTTÖOHJE Servia S solutions Versio 1.0 Servia S solutions Servia Finland Oy PL 1188 (Microkatu 1) 70211 KUOPIO puh. (017) 441 2780 info@servia.fi www.servia.fi 2001 2004 Servia Finland Oy. Kaikki oikeudet
ETAPPI ry JOOMLA 2.5 Mediapaja. Artikkeleiden hallinta ja julkaisu
ETAPPI ry JOOMLA 2.5 Artikkeleiden hallinta ja julkaisu ETAPPI ry JOOMLA 2.5 Sivu 1(16) Sisällysluettelo 1 Joomla! sivuston sisällöntuotanto... 2 2 Artikkeleiden julkaisu sivustolla... 4 3 Artikkelin julkaisemista
JOVISION IP-KAMERA Käyttöohje
JOVISION IP-KAMERA Käyttöohje 1 Yleistä... 2 2 Kameran kytkeminen verkkoon... 2 2.1 Tietokoneella... 2 2.2 Älypuhelimella / tabletilla... 5 3 Salasanan vaihtaminen... 8 3.1 Salasanan vaihtaminen Windows
Videon tallentaminen Virtual Mapista
Videon tallentaminen Virtual Mapista Kamera-ajon tekeminen Karkean kamera ajon teko onnistuu nopeimmin Katseluohjelmassa (Navigointi > Näkymät > Tallenna polku). Liikeradan ja nopeuden tarkka hallinta
Kirkkopalvelut Office365, Opiskelijan ohje 1 / 17 IT Juha Nalli 22.12.2015
Kirkkopalvelut Office365, Opiskelijan ohje 1 / 17 Oppilaat saavat vuoden 2016 alusta käyttöönsä oppilaitoksen sähköpostin ja muita palveluita Microsoftin Office365:sta. Oppilaiden sähköposti on muotoa
TIE PRINCIPLES OF PROGRAMMING LANGUAGES Eiffel-ohjelmointikieli
TIE-20306 PRINCIPLES OF PROGRAMMING LANGUAGES Eiffel-ohjelmointikieli Seminaariesitelmä ryhmä 24 Markku Ahokas Jani Kuitti i SISÄLLYSLUETTELO 1. YLEISTÄ EIFFELISTÄ... 1 1.1 Historia ja tausta... 1 1.2
Yhteentoimivuusalusta: Miten saadaan ihmiset ja koneet ymmärtämään toisiaan paremmin?
Yhteentoimivuusalusta: Miten saadaan ihmiset ja koneet ymmärtämään toisiaan paremmin? Avoin verkkoalusta ihmisen ja koneen ymmärtämien tietomääritysten tekemiseen Riitta Alkula 20.3.2019 Esityksen sisältö