Upgrade to Pro — share decks privately, control downloads, hide ads and more …

低レイヤーグラフィックAPI Vulkanを始めよう

Fadis
July 22, 2017

低レイヤーグラフィックAPI Vulkanを始めよう

次世代グラフィックAPI Vulkanがどんなヤツであるかを、実際のコードを交えて解説します。
これは2017年7月22日に行われた 第13回 カーネル/VM探検隊 の発表資料です。

Fadis

July 22, 2017
Tweet

More Decks by Fadis

Other Decks in Programming

Transcript

  1. Λ࢝ΊΑ͏
    ௿ϨΠϠʔάϥϑΟοΫ"1*
    NAOMASA MATSUBAYASHI

    View Slide

  2. ౳Ͱ஌ΒΕΔ͕ࡦఆͨ͠
    ৽͍͠%άϥϑΟΫε"1*
    https://jp.khronos.org/vulkan/

    View Slide

  3. ͳͥͱ͸ผͷ
    "1*͕ඞཁʹͳͬͨͷ͔

    View Slide

  4. άϥϑΟοΫύΠϓϥΠϯ
    ௖఺Λϫʔϧυ࠲ඪܥʹม׵
    ௖఺ʹ͓͚ΔӄӨΛܭࢉ
    ௖఺ΛεΫϦʔϯ࠲ඪܥʹม׵
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ςΫενϟΛಡΜͰӄӨͱ߹੒
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽
    ଠݹͷ(16Ͱ͸͜ͷύΠϓϥΠϯ͕
    ϋʔυ΢ΣΞͱͯ͠උΘ͍ͬͯͨ
    ௖఺୯Ґͷॲཧ
    ըૉ୯Ґͷॲཧ

    View Slide

  5. glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,tw,th,
    0,GL_RGB,GL_UNSIGNED_BYTE,texture);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse_color);
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular_color);
    glLightfv(GL_LIGHT0,GL_AMBIENT,ambient_color);

    glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,material_color);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glDrawArrays(GL_TRIANGLES,0,vertex_count);
    ౰࣌ͷ
    ςΫενϟͷಡΈํΛࢦఆ
    ϥΠτΛ༗ޮʹ͢Δ
    ϥΠτͷ৭Λࢦఆ
    ਂ౓ςετΛ༗ޮʹ͢Δ
    എ໘ΧϦϯάΛ༗ޮʹ͢Δ
    ϑϨʔϜόοϑΝΛফڈʹͯ͠
    %SBXίʔϧ

    View Slide

  6. ౰࣌ͷ ͸
    ϋʔυ΢ΣΞʹඋΘͬͨ
    ύΠϓϥΠϯͷಈ࡞Λࢦఆ͢ΔϨδελΛ
    ಛఆͷϋʔυ΢ΣΞʹґଘ͠ͳ͍Ͱ
    ୟͨ͘Ίͷํ๏Λఏڙ͢Δϥού
    ͱ͍͏৭͕ڧ͍

    View Slide

  7. ௖఺γΣʔμ
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ϑϥάϝϯτ
    γΣʔμ
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽ ύΠϓϥΠϯதͷՕॴʹ
    ೚ҙͷܭࢉ͕Ͱ͖Δϓϩηοα͕
    ૊Έࠐ·ΕΔࣄʹͳͬͨ
    ϓϩάϥϚϒϧγΣʔμ
    ϗετ͔Β௖఺Λ໯ͬͯ
    ೚ҙͷܭࢉΛͯ͠
    ௖఺Λు͘
    ϐΫηϧͷଐੑ஋Λ໯ͬͯ
    ೚ҙͷܭࢉΛͯ͠
    ϐΫηϧͷ৭Λు͘

    View Slide

  8. ௖఺γΣʔμ
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ϑϥάϝϯτ
    γΣʔμ
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽
    ϓϩάϥϚϒϧγΣʔμ
    ܭࢉଟ͗͢ࢮʹͦ͏
    σʔλ͕དྷͳͯ͘Ջ
    ೚ҙͷܭࢉʹ͔͔Δ͕࣌ؒಡΊͳ͍
    ύΠϓϥΠϯΛ
    ࠷େͷޮ཰Ͱಈ͔͢ʹ͸
    શͯͷεςʔδ͕
    ಉ͘͡Β͍ͷ࣌ؒͰ
    ׬ྃ͢Δඞཁ͕͋Δ͕

    View Slide

  9. ϢχϑΝΠυγΣʔμΞʔΩςΫνϟ
    ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα
    ʜ
    ൚༻తͳܭࢉ͕Ͱ͖ΔϓϩηοαΛ
    େྔʹฒ΂ͨΞʔΩςΫνϟ
    άϥϑΟοΫύΠϓϥΠϯ͸
    ͜ͷ্Ͱಈ͘ιϑτ΢ΣΞͱ࣮ͯ͠૷͞ΕΔ
    ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα
    ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα ϓϩηοα

    View Slide

  10. ιϑτ΢ΣΞʹͳͬͨύΠϓϥΠϯ͸
    ͲΜͲΜෳࡶʹͳͬͨ
    ௖఺γΣʔμ
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ϑϥάϝϯτγΣʔμ
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽
    δΦϝτϦγΣʔμ
    ςηϨʔγϣϯ੍ޚγΣʔμ
    ςηϨʔγϣϯධՁγΣʔμ
    Ͱ͔͍ϓϦϛςΟϒΛ෼ׂ
    ίϯϐϡʔτγΣʔμ
    (16ଆͰ࣮ߦ͢Δ
    ίʔυͷੜ੒ʹ͸
    ϛϦඵΦʔμʔͷ
    ͕͔͔࣌ؒΔ

    View Slide

  11. ஗ԆϨϯμϦϯά
    ܗঢ়͚ͩΛςΫενϟʹඳ͘
    ӄӨΛܭࢉ 44"0Λܭࢉ
    ඃࣸքਂ౓Λܭࢉ
    τʔϯϚοϓ
    ࠷ॳʹܗঢ়ΛςΫενϟʹඳ͍ͯ
    ޙͷෳࡶͳॲཧ͸ը૾ॲཧͱ࣮ͯ͠૷

    View Slide

  12. ϚςϦΞϧ͝ͱʹҟͳΔγΣʔμ
    ࠓ೔ͷϨϯμϦϯάͰ͸
    ඳըର৅ͷࡐ࣭͝ͱʹγΣʔμΛ༻ҙ͠
    ͭͷ෺ମΛ୔ࢁͷϨϯμϦϯά݁Ռͷ
    ૊Έ߹ΘͤͰදݱ͢Δ
    ඵͷίϚͷϨϯμϦϯάͷؒʹߦΘΕΔ
    %SBXίʔϧ͸਺ඦճʹ΋ͳΔ
    ͨͩͭ͠ͷ%SBXίʔϧͷฒྻ౓͸௿͍
    ඃࣸքਂ౓Λܭࢉ
    τʔϯϚοϓ

    View Slide

  13. ͸ੲ͔Βͷ"1*ΛकΓଓ͚ͨ
    ·ΔͰͦ͜ʹҰॠͰϨϯμϦϯάํ๏͕
    ੾ΓସΘΔϨδελ͕͋Δ͔ͷΑ͏ʹ
    ϨϯμϦϯάํ๏ΛϑϨʔϜͷؒʹ
    Կඦճ΋੾Γସ͑ͯ%SBXίʔϧΛ౤͛Δ
    ͕ͩ(16ଆͰ࣮ߦ͢Δ
    ίʔυͷ੾Γସ͑ʹ͸
    ͕͔͔࣌ؒΔ

    View Slide

  14. ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ઃఆΛม͑Δ
    ը໘ʹඳ͘
    υϥΠό͸ίϚϯυΛه࿥ͯ͠
    (16Ͱ࣮ߦ͢Δίʔυͷੜ੒Λ஗Ԇͤ͞Δ
    υϥΠό͸ը໘ʹԿ͔͕
    ൓ө͞Εͳ͚Ε͹
    ͳΒͳ͘ͳͬͨ࣌఺Ͱ
    ͦ͜·ͰͷॲཧΛશͯ·ͱΊͨ
    ίʔυΛੜ੒
    υϥΠό͸
    σʔλͷґଘؔ܎Λௐ΂
    ಉ࣌ʹ࣮ߦͰ͖Δ෺͸
    ಉ࣌ʹ࣮ߦ͢Δ

    View Slide

  15. ϑϨʔϜ໨
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ઃఆΛม͑Δ
    ը໘ʹඳ͘
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ςΫενϟʹඳ͘
    ઃఆΛม͑Δ
    ઃఆΛม͑Δ
    ը໘ʹඳ͘
    ϑϨʔϜ໨
    υϥΠό͸
    ίϚϯυྻΛൺֱͯ͠
    Ұ౓ੜ੒ͨ͠όΠφϦ͕
    ࠶ར༻Մೳ͔Λ൑அ͢Δ

    View Slide

  16. υϥΠόͷ࢓ࣄ͕૿͑͗ͯ͢
    υϥΠόͷ࣮ߦʹཁ͢Δ$16Ͱͷܭࢉ࣌ؒͱ
    े෼ͳ඼࣭ͷυϥΠόͷ࣮૷ίετ͕
    ਂࠁͳ໰୊ʹͳͬͨ

    View Slide

  17. ͸ޓ׵ੑΛେࣄʹ͠ଓ͚ͨ݁Ռ
    "1*ͷϞσϧͱ࣮ࡍͷϋʔυ΢ΣΞ͕
    େ͖͘ဃ཭ͯ͠͠·ͬͨ
    υϥΠόͷ࢓ࣄ͕૿͑͗ͯ͢
    υϥΠόͷ࣮ߦʹཁ͢Δ$16Ͱͷܭࢉ࣌ؒͱ
    े෼ͳ඼࣭ͷυϥΠόͷ࣮૷ίετ͕
    ਂࠁͳ໰୊ʹͳͬͨ
    ݱ୅ͷϋʔυ΢ΣΞͰߦͳ͍ͬͯΔ͜ͱΛ
    ͦͷ··ϞσϧԽͨ͠"1*Λ࡞Ε͹
    ͜ΕΒͷ໰୊ΛղܾͰ͖Δ

    View Slide

  18. ݱ୅ͷ(16͕උ͑ΔػೳΛ
    Ͱ͖Δ͚ͩͦͷ··ୟͨ͘Ίͷ
    ৽͍͠%άϥϑΟοΫ"1*

    View Slide

  19. Ͱඳ͘·ͰͷྲྀΕ
    7VMLBOΠϯελϯεΛ࡞Δ
    ࢖͏෺ཧσόΠεΛબͿ
    ΢Οϯυ΢γεςϜ͔ΒαʔϑΣεΛ΋Β͏
    ࿦ཧσόΠεΛ࡞Δ
    ඳըઌͷΠϝʔδΛ࡞Δ
    ίϚϯυόοϑΝΛ࡞Δ
    ඞཁͳσʔλΛ(16ʹૹΔ
    γΣʔμϞδϡʔϧΛ࡞Δ
    σεΫϦϓληοτΛ࡞Δ
    εϫοϓνΣΠϯΛ࡞Δ

    View Slide

  20. ίϚϯυόοϑΝΛ࡞Δ
    ඞཁͳσʔλΛ(16ʹૹΔ
    γΣʔμϞδϡʔϧΛ࡞Δ
    σεΫϦϓληοτΛ࡞Δ
    ϨϯμʔύεΛ࡞Δ
    ϑϨʔϜόοϑΝΛ࡞Δ
    ύΠϓϥΠϯΛ࡞Δ
    ίϚϯυόοϑΝʹඞཁͳίϚϯυΛੵΉ
    εϫοϓνΣΠϯ͔Β࣍ͷΠϝʔδΛ΋Β͏
    ίϚϯυΛσόΠεͷΩϡʔʹྲྀ͢
    ΠϝʔδΛදࣔՄೳʹ͢Δ

    View Slide

  21. σεΫϦϓληοτ
    ύΠϓϥΠϯ
    Ϩϯμʔύε
    ͭͷॏཁͳΦϒδΣΫτ
    ͲͷΑ͏ͳσʔλΛ࢖ͬͯ
    ඳըΛߦ͏͔Λ
    ఆٛͨ͠΋ͷ
    ͲͷΑ͏ͳॱংͰ
    ඳըΛߦ͏͔Λ
    ఆٛͨ͠΋ͷ
    ͲͷΑ͏ͳํ๏Ͱ
    ඳըΛߦ͏͔Λ
    ఆٛͨ͠΋ͷ
    ͭͷΦϒδΣΫτ͕ଗͬͨ࣌
    ༐ऀ͕௖఺όοϑΝΛ౤͛Δͱ(16͕ಈ͖ͩ͢

    View Slide

  22. const auto avail_ext=vk::enumerateInstanceExtensionProperties();
    for(const char *w:ext)
    if(std::find_if(avail_ext.begin(),avail_ext.end(),
    [&](const auto &v){return !strcmp(v.extensionName,w);}
    )==avail_ext.end()) throw ExtensionNotAvailable();
    const auto avail_layers=vk::enumerateInstanceLayerProperties();
    for(const char *w:layers)
    if(std::find_if(avail_layers.begin(),avail_layers.end(),
    [&](const auto &v){return !strcmp(v.layerName,w);}
    )==avail_layers.end())throw LayerNotAvailable();
    const auto app_info = vk::ApplicationInfo(
    app_name.c_str(),VK_MAKE_VERSION(1,0,0),”HogeEngine",
    VK_MAKE_VERSION(1,0,0),VK_API_VERSION_1_0
    );
    instance=vk::createInstance(
    vk::InstanceCreateInfo()
    .setPApplicationInfo(&app_info)
    .setEnabledExtensionCount(ext.size())
    .setPpEnabledExtensionNames(ext.data())
    .setEnabledLayerCount(layers.size())
    .setPpEnabledLayerNames(layers.data())
    );
    ͷΠϯελϯεΛ࡞Δ
    ΞϓϦέʔγϣϯ͕ඞཁͱ͍ͯ͠Δ
    ֦ுͱϨΠϠʔΛ
    γεςϜͷϥϯλΠϜ͕
    αϙʔτ͍ͯ͠Δ͔Λௐ΂Δ

    View Slide

  23. const auto avail_ext=vk::enumerateInstanceExtensionProperties();
    for(const char *w:ext)
    if(std::find_if(avail_ext.begin(),avail_ext.end(),
    [&](const auto &v){return !strcmp(v.extensionName,w);}
    )==avail_ext.end()) throw ExtensionNotAvailable();
    const auto avail_layers=vk::enumerateInstanceLayerProperties();
    for(const char *w:layers)
    if(std::find_if(avail_layers.begin(),avail_layers.end(),
    [&](const auto &v){return !strcmp(v.layerName,w);}
    )==avail_layers.end())throw LayerNotAvailable();
    const auto app_info = vk::ApplicationInfo(
    app_name.c_str(),VK_MAKE_VERSION(1,0,0),”HogeEngine",
    VK_MAKE_VERSION(1,0,0),VK_API_VERSION_1_0
    );
    instance=vk::createInstance(
    vk::InstanceCreateInfo()
    .setPApplicationInfo(&app_info)
    .setEnabledExtensionCount(ext.size())
    .setPpEnabledExtensionNames(ext.data())
    .setEnabledLayerCount(layers.size())
    .setPpEnabledLayerNames(layers.data())
    );
    ͷΠϯελϯεΛ࡞Δ
    createInstanceͰ
    ΠϯελϯεΛ࡞Δ
    ͜ͷ࣌ɺ࢖͍͍֦ͨுͱϨΠϠʔΛࢦఆ͢Δ

    View Slide

  24. ֦ு
    ͷن֨ʹ͸ؚ·Ε͍ͯͳ͍͕
    ಛఆͷ࣮૷ʹ͓͍ͯར༻Ͱ͖Δػೳ
    ྫ4-J౳Ͱෳ਺ͷ(16Λ࿈ಈͤ͞Δҝͷ֦ு
    7,@,)[email protected]@HSPVQ
    ϨΠϠʔ
    ͷ"1*ͷݺͼग़͠ΛϑοΫͯ͠
    ෇ՃతͳػೳΛఏڙ͢ΔϥΠϒϥϦ
    ྫؔ਺ʹෆਖ਼ͳҾ਺͕౉͞Εͨ৔߹ʹσόοάग़ྗΛߦ͏
    7,@-":&[email protected]/"3(@[email protected]

    View Slide

  25. auto devices=instance.enumeratePhysicalDevices();
    if(devices.empty())throw DeviceNotAvailable();
    const auto physical_device=std::find_if(
    devices.begin(),devices.end(),[&](const auto &d)->bool{
    const auto prop=d.getProperties();
    // (தུ) σόΠεͷ৘ใΛݟͯ࢖͍ͨ͘ͳ͍σόΠεΛআ֎͢Δ
    return true;
    }
    );
    if(physical_device==devices.end())throw DeviceNotAvailable();
    ࢖͏෺ཧσόΠεΛબͿ
    σόΠεͷछྨ΍ݶք஋
    αϙʔτ͢Δ֦ு౳Λௐ΂ͯ࢖͏(16ΛબͿ
    Ͱ͸ͭͷΞϓϦέʔγϣϯ͕
    ෳ਺ͷ(16Λಈ͔ͯ͠΋ྑ͍
    ͨͩ͠(16ʹಛผͳ࢓૊Έ͕ͳ͍ݶΓ
    (16ؒͷσʔλͷసૹ͸$16Λհ͢ࣄʹͳΔ

    View Slide

  26. ඳը݁ՌΛը໘ʹදࣔ͢ΔͨΊʹ͸
    ΢Οϯυ΢γεςϜͷαʔϑΣεͱ
    ͷαʔϑΣεΛ݁ͼ͚ͭΔඞཁ͕͋Δ
    VK_KHR_win32_surface֦ு
    VK_KHR_xcb_surface֦ு
    VK_KHR_surface֦ு
    VkSurfaceKHRΛ࡞ΕΔ
    VkSurfaceKHRͱHWNDΛ݁ͼ͚ͭΔ
    VkSurfaceKHRͱxcb_window_tΛ݁ͼ͚ͭΔ
    VK_KHR_wayland_surface֦ு
    VkSurfaceKHRͱwl_surfaceΛ݁ͼ͚ͭΔ

    View Slide

  27. https://www.khronos.org/registry/vulkan/specs/1.0-extensions/
    html/vkspec.html#VK_NN_vi_surface
    nn::vi::LayerͳΔฉ͖׳Εͳ͍
    ΢Οϯυ΢γεςϜͱ݁ͼ͚ͭΔͨΊͷ֦ு
    ೚ఱಊ֦ு

    View Slide

  28. ४ڌ੡඼ϨδετϦ
    https://www.khronos.org/conformance/adopters/conformant-
    products#vulkan

    View Slide

  29. int scr;
    xcb.reset(
    xcb_connect(nullptr,&scr),[](auto p){if(p)xcb_disconnect(p);}
    );
    if(xcb_connection_has_error(xcb.get())>0)
    throw XServerUnreachable();
    xcb_screen_t *xcb_screen=nullptr;
    const xcb_setup_t * const xcb_setup=xcb_get_setup(xcb.get());
    xcb_screen_iterator_t xcb_screen_iter=
    xcb_setup_roots_iterator(xcb_setup);
    while(scr-->0)xcb_screen_next(&xcb_screen_iter);
    xcb_screen=xcb_screen_iter.data;
    xcb_window=xcb_generate_id(xcb_connection.get());
    const uint32_t value_mask=XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK;
    const std::array value_list{{
    xcb_screen->black_pixel,XCB_EVENT_MASK_KEY_RELEASE|
    XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_STRUCTURE_NOTIFY,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    }};
    xcb_create_window(
    xcb.get(),XCB_COPY_FROM_PARENT,xcb_window,xcb_screen->root,
    0,0,width,height,0,XCB_WINDOW_CLASS_INPUT_OUTPUT,
    xcb_screen->root_visual,value_mask,value_list.data()
    ΢Οϯυ΢γεςϜ͔ΒαʔϑΣεΛ΋Β͏
    9αʔόʹ઀ଓ͢Δ

    View Slide

  30. xcb_screen_iterator_t xcb_screen_iter=
    xcb_setup_roots_iterator(xcb_setup);
    while(scr-->0)xcb_screen_next(&xcb_screen_iter);
    xcb_screen=xcb_screen_iter.data;
    xcb_window=xcb_generate_id(xcb_connection.get());
    const uint32_t value_mask=XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK;
    const std::array value_list{{
    xcb_screen->black_pixel,XCB_EVENT_MASK_KEY_RELEASE|
    XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_STRUCTURE_NOTIFY,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    }};
    xcb_create_window(
    xcb.get(),XCB_COPY_FROM_PARENT,xcb_window,xcb_screen->root,
    0,0,width,height,0,XCB_WINDOW_CLASS_INPUT_OUTPUT,
    xcb_screen->root_visual,value_mask,value_list.data()
    );
    xcb_intern_atom_cookie_t xcb_cookie=
    xcb_intern_atom(xcb.get(),1,12,"WM_PROTOCOLS");
    std::unique_ptr reply(
    xcb_intern_atom_reply(xcb.get(),xcb_cookie,0)
    );
    xcb_intern_atom_cookie_t cookie2=
    xcb_intern_atom(xcb.get(),0,16,"WM_DELETE_WINDOW");
    atom_wm_delete_window=
    ΢Οϯυ΢γεςϜ͔ΒαʔϑΣεΛ΋Β͏
    ΢Οϯυ΢Λ࡞Δ

    View Slide

  31. xcb_screen->root_visual,value_mask,value_list.data()
    );
    xcb_intern_atom_cookie_t xcb_cookie=
    xcb_intern_atom(xcb.get(),1,12,"WM_PROTOCOLS");
    std::unique_ptr reply(
    xcb_intern_atom_reply(xcb.get(),xcb_cookie,0)
    );
    xcb_intern_atom_cookie_t cookie2=
    xcb_intern_atom(xcb.get(),0,16,"WM_DELETE_WINDOW");
    atom_wm_delete_window=
    xcb_intern_atom_reply(xcb.get(),cookie2,0);
    xcb_change_property(
    xcb.get(),XCB_PROP_MODE_REPLACE,xcb_window,(*reply).atom,
    4,32,1,&(*atom_wm_delete_window).atom
    );
    xcb_map_window(xcb.get(),xcb_window);
    const uint32_t coords[]={0,0};
    xcb_configure_window(
    xcb.get(),xcb_window,
    XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y,coords
    );
    xcb_flush(xcb.get());
    surface = instance.createXcbSurfaceKHR(
    vk::XcbSurfaceCreateInfoKHR()
    .setConnection(xcb.get())
    ΢Οϯυ΢γεςϜ͔ΒαʔϑΣεΛ΋Β͏
    ͦͷଞࡉ͔͍ઃఆΛͯ͠qVTI

    View Slide

  32. xcb_intern_atom(xcb.get(),0,16,"WM_DELETE_WINDOW");
    atom_wm_delete_window=
    xcb_intern_atom_reply(xcb.get(),cookie2,0);
    xcb_change_property(
    xcb.get(),XCB_PROP_MODE_REPLACE,xcb_window,(*reply).atom,
    4,32,1,&(*atom_wm_delete_window).atom
    );
    xcb_map_window(xcb.get(),xcb_window);
    const uint32_t coords[]={0,0};
    xcb_configure_window(
    xcb.get(),xcb_window,
    XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y,coords
    );
    xcb_flush(xcb.get());
    surface = instance.createXcbSurfaceKHR(
    vk::XcbSurfaceCreateInfoKHR()
    .setConnection(xcb.get())
    .setWindow(xcb_window)
    );
    ΢Οϯυ΢γεςϜ͔ΒαʔϑΣεΛ΋Β͏
    xcb_window͔Β
    ͷαʔϑΣεΛ࡞Δ

    View Slide

  33. σόΠεʹඋΘ͍ͬͯΔΩϡʔΛௐ΂Δ
    ͷΩϡʔͱ͸
    (16্Ͱ࣮ߦ͢ΔίϚϯυͷ଴ػྻ
    QueueFlagBits::eGraphics
    σόΠε͸छྨҎ্ͷΩϡʔϑΝϛϦΛαϙʔτ͢Δ
    ΩϡʔϑΝϛϦʹΑͬͯྲྀͤΔίϚϯυʹ੍ݶ͕͋Δ
    ͜ͷϏοτཱ͕͍ͬͯΔΩϡʔϑΝϛϦʹ͸ඳը໋ྩΛ౤͛ͯྑ͍
    QueueFlagBits::eCompute
    ͜ͷϏοτཱ͕͍ͬͯΔΩϡʔϑΝϛϦ͸ܭࢉ໋ྩΛ౤͛ͯྑ͍
    QueueFlagBits::eTransfer
    ͜ͷϏοτཱ͕͍ͬͯΔΩϡʔϑΝϛϦ͸σʔλసૹ໋ྩΛ౤͛ͯྑ͍
    eTransferཱ͔͍ͬͯ͠ͳ͍෺͕શ෦͍͚Δ෺ͱผʹ͋Δ
    = ͨͿΜϓϩηοαͱಠཱͯ͠ಈ͘DMAΛ࢖͏ͨΊͷΩϡʔϑΝϛϦ

    View Slide

  34. uint32_t graphics_queue_index = 0u;
    uint32_t present_queue_index = 0u;
    const auto queue_props=
    physical_device->getQueueFamilyProperties();
    std::vector< VkBool32 > supportsPresent(queue_props.size());
    for(uint32_t i=0;iphysical_device->getSurfaceSupportKHR(
    i,surface, &supportsPresent[i]
    );
    graphics_queue_index=std::distance(
    queue_props.begin(),
    std::find_if(
    queue_props.begin(),queue_props.end(),[](const auto &v){
    return bool(v.queueFlags& vk::QueueFlagBits::eGraphics);
    }
    )
    );
    present_queue_index=(
    graphics_queue_index!=queue_props.size()&&
    supportsPresent[ graphics_queue_index ]==VK_TRUE
    )?
    graphics_queue_index:
    ඳըʹ࢖͑ͦ͏ͳΩϡʔΛબͿ
    ඳը໋ྩΛ౤͛ΒΕΔΩϡʔΛ୳͢

    View Slide

  35. queue_props.begin(),queue_props.end(),[](const auto &v){
    return bool(v.queueFlags& vk::QueueFlagBits::eGraphics);
    }
    )
    );
    present_queue_index=(
    graphics_queue_index!=queue_props.size()&&
    supportsPresent[ graphics_queue_index ]==VK_TRUE
    )?
    graphics_queue_index:
    std::distance(
    supportsPresent.begin(),
    std::find(
    supportsPresent.begin(),supportsPresent.end(),VK_TRUE
    )
    );
    if(
    graphics_queue_index==queue_props.size()||
    present_queue_index==queue_props.size()
    ) throw UnableToCreateSwapChain();
    ඳըʹ࢖͑ͦ͏ͳΩϡʔΛબͿ
    ϨϯμϦϯά݁ՌͷදࣔཁٻΛ
    ౤͛ΒΕΔΩϡʔΛ୳͢

    View Slide

  36. const float priority=0.0f;
    const auto features=physical_device->getFeatures();
    std::vector queues{
    vk::DeviceQueueCreateInfo()
    .setQueueFamilyIndex(graphics_queue_index)
    .setQueueCount(1)
    .setPQueuePriorities(&priority)
    };
    if(graphics_queue_index!=present_queue_index)
    queues.emplace_back(
    vk::DeviceQueueCreateInfo()
    .setQueueFamilyIndex(present_queue_index)
    .setQueueCount(1)
    .setPQueuePriorities(&priority)
    );
    device=physical_device->createDevice(
    vk::DeviceCreateInfo()
    .setQueueCreateInfoCount(queues.size())
    .setPQueueCreateInfos(queues.data())
    .setEnabledLayerCount(dlayers.size())
    .setPpEnabledLayerNames(dlayers.data())
    .setEnabledExtensionCount(dext.size())
    ඞཁͳΩϡʔʹؔ͢Δ৘ใΛ༻ҙ͢Δ
    ࿦ཧσόΠεΛ࡞Δ

    View Slide

  37. .setQueueCount(1)
    .setPQueuePriorities(&priority)
    };
    if(graphics_queue_index!=present_queue_index)
    queues.emplace_back(
    vk::DeviceQueueCreateInfo()
    .setQueueFamilyIndex(present_queue_index)
    .setQueueCount(1)
    .setPQueuePriorities(&priority)
    );
    device=physical_device->createDevice(
    vk::DeviceCreateInfo()
    .setQueueCreateInfoCount(queues.size())
    .setPQueueCreateInfos(queues.data())
    .setEnabledLayerCount(dlayers.size())
    .setPpEnabledLayerNames(dlayers.data())
    .setEnabledExtensionCount(dext.size())
    .setPpEnabledExtensionNames(dext.data())
    .setPEnabledFeatures(&features)
    );
    graphics_queue=device.getQueue(graphics_queue_index,0);
    present_queue=device.getQueue(present_queue_index,0);
    createDeviceʹ
    ඞཁͳ֦ுɺϨΠϠʔɺΩϡʔͷ৘ใΛ౉ͯ͠
    ࿦ཧσόΠεΛ࡞Δ
    ࿦ཧσόΠεΛ࡞Δ
    Ҏ߱GPUʹର͢Δ΄ͱΜͲͷૢ࡞͸
    ࿦ཧσόΠεʹରͯ͠ߦ͏ࣄʹͳΔ

    View Slide

  38. εϫοϓνΣΠϯ
    ඳըઌͷΠϝʔδ͕ຕ͔͠ͳ͍ͱ
    ඳ͍͍ͯΔ్தͷঢ়ଶ͕ը໘ʹදࣔ͞ΕΔڪΕ͕͋Δ
    ඳըઌͷΠϝʔδΛෳ਺༻ҙͯ͠
    ຕඳ͖ऴ͑Δຖʹ੾Γସ͑Δ

    View Slide

  39. const auto surface_capabilities=
    physical_device->getSurfaceCapabilitiesKHR(surface);
    const auto present_modes=
    physical_device->getSurfacePresentModesKHR(surface);
    vk::Extent2D swapchain_extent;
    if(surface_capabilities.currentExtent.width==(uint32_t)-1){
    sc_extent.width = width;
    sc_extent.height = height;
    }else{
    sc_extent=surface_capabilities.currentExtent;
    width=surface_capabilities.currentExtent.width;
    height=surface_capabilities.currentExtent.height;
    }
    const uint32_t sc_image_count=
    std::min(surface_capabilities.minImageCount+1,
    surface_capabilities.maxImageCount);
    const vk::SurfaceTransformFlagBitsKHR transform_flag=
    (surface_capabilities.supportedTransforms&
    vk::SurfaceTransformFlagBitsKHR::eIdentity)?
    vk::SurfaceTransformFlagBitsKHR::eIdentity:
    surface_capabilities.currentTransform;
    ϋʔυ΢ΣΞʹΑͬͯ͸εϫοϓνΣΠϯͷ
    ը૾ͷαΠζ͕ݻఆ͞Ε͍ͯΔ͜ͱ͕͋Δ
    SurfaceCapabiitiesΛௐ΂ͯ
    -1͕ηοτ͞Ε͍ͯͨΒ೚ҙͷαΠζΛࢦఆͰ͖Δ
    εϫοϓνΣΠϯ

    View Slide

  40. const auto surface_capabilities=
    physical_device->getSurfaceCapabilitiesKHR(surface);
    const auto present_modes=
    physical_device->getSurfacePresentModesKHR(surface);
    vk::Extent2D swapchain_extent;
    if(surface_capabilities.currentExtent.width==(uint32_t)-1){
    sc_extent.width = width;
    sc_extent.height = height;
    }else{
    sc_extent=surface_capabilities.currentExtent;
    width=surface_capabilities.currentExtent.width;
    height=surface_capabilities.currentExtent.height;
    }
    const uint32_t sc_image_count=
    std::min(surface_capabilities.minImageCount+1,
    surface_capabilities.maxImageCount);
    const vk::SurfaceTransformFlagBitsKHR transform_flag=
    (surface_capabilities.supportedTransforms&
    vk::SurfaceTransformFlagBitsKHR::eIdentity)?
    vk::SurfaceTransformFlagBitsKHR::eIdentity:
    surface_capabilities.currentTransform;
    εϫοϓνΣΠϯͷ࠷খຕ਺ͱ࠷େຕ਺͸
    ϋʔυ΢ΣΞʹΑͬͯҟͳΔ
    ࡞੒͢ΔεϫοϓνΣΠϯͷຕ਺͸
    ͜ͷൣғ಺ͷ஋Ͱͳ͚Ε͹ͳΒͳ͍
    εϫοϓνΣΠϯ

    View Slide

  41. swapchain=device.createSwapchainKHR(
    vk::SwapchainCreateInfoKHR().setSurface(surface)
    .setMinImageCount(sc_image_count)
    .setImageFormat(format)
    .setImageColorSpace(color_space)
    .setImageExtent({sc_extent.width, sc_extent.height})
    .setImageArrayLayers(1)
    .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment)
    .setImageSharingMode(vk::SharingMode::eExclusive)
    .setQueueFamilyIndexCount(0)
    .setPQueueFamilyIndices(nullptr)
    .setPreTransform(transform_flag)
    .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
    .setPresentMode(vk::PresentModeKHR::eFifo)
    .setClipped(true)
    );
    swapchain_images=device.getSwapchainImagesKHR(swapchain);
    for(auto &swapchain_image:swapchain_images){
    swapchain_views.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo().setImage(swapchain_image)
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(format)
    ࢦఆͨ͠αΠζͱϑΥʔϚοτͷΠϝʔδΛ
    ࢦఆͨ͠ຕ਺࣋ͭεϫοϓνΣΠϯΛ࡞Δ
    εϫοϓνΣΠϯ

    View Slide

  42. .setPQueueFamilyIndices(nullptr)
    .setPreTransform(transform_flag)
    .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
    .setPresentMode(vk::PresentModeKHR::eFifo)
    .setClipped(true)
    );
    swapchain_images=device.getSwapchainImagesKHR(swapchain);
    for(auto &swapchain_image:swapchain_images){
    swapchain_views.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo().setImage(swapchain_image)
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(format)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eColor,0,1,0,1
    ))
    )
    );
    }
    ϓϨθϯτϞʔυ
    vk::PresentModeKHR::eImmediate
    ඳըΛऴ͑ͨΠϝʔδΛදࣔՄೳঢ়ଶʹͨ͠ޙ
    ͦΕ͕͍ͭදࣔ͞ΕΔ͔Λίϯτϩʔϧ͢Δ
    ը໘ͷਨ௚ಉظΛ଴ͨͣʹ௚ͪʹΠϝʔδΛೖΕସ͑Δ
    ςΟΞϦϯά͕ى͜ΔՄೳੑ͕͋Δ͕࠷΋ૣ͘ද͕ࣔߋ৽͞ΕΔ
    vk::PresentModeKHR::eMailbox
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͸ഁغ͞ΕΔ
    vk::PresentModeKHR::eFIFO
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͔Βॱʹදࣔ͞ΕΔ

    View Slide

  43. .setPQueueFamilyIndices(nullptr)
    .setPreTransform(transform_flag)
    .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
    .setPresentMode(vk::PresentModeKHR::eFifo)
    .setClipped(true)
    );
    swapchain_images=device.getSwapchainImagesKHR(swapchain);
    for(auto &swapchain_image:swapchain_images){
    swapchain_views.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo().setImage(swapchain_image)
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(format)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eColor,0,1,0,1
    ))
    )
    );
    }
    ϓϨθϯτϞʔυ
    vk::PresentModeKHR::eImmediate
    ඳըΛऴ͑ͨΠϝʔδΛදࣔՄೳঢ়ଶʹͨ͠ޙ
    ͦΕ͕͍ͭදࣔ͞ΕΔ͔Λίϯτϩʔϧ͢Δ
    ը໘ͷਨ௚ಉظΛ଴ͨͣʹ௚ͪʹΠϝʔδΛೖΕସ͑Δ
    ςΟΞϦϯά͕ى͜ΔՄೳੑ͕͋Δ͕࠷΋ૣ͘ද͕ࣔߋ৽͞ΕΔ
    vk::PresentModeKHR::eMailbox
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͸ഁغ͞ΕΔ
    vk::PresentModeKHR::eFIFO
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͔Βॱʹදࣔ͞ΕΔ

    View Slide

  44. .setPQueueFamilyIndices(nullptr)
    .setPreTransform(transform_flag)
    .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
    .setPresentMode(vk::PresentModeKHR::eFifo)
    .setClipped(true)
    );
    swapchain_images=device.getSwapchainImagesKHR(swapchain);
    for(auto &swapchain_image:swapchain_images){
    swapchain_views.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo().setImage(swapchain_image)
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(format)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eColor,0,1,0,1
    ))
    )
    );
    }
    ϓϨθϯτϞʔυ
    vk::PresentModeKHR::eImmediate
    ඳըΛऴ͑ͨΠϝʔδΛදࣔՄೳঢ়ଶʹͨ͠ޙ
    ͦΕ͕͍ͭදࣔ͞ΕΔ͔Λίϯτϩʔϧ͢Δ
    ը໘ͷਨ௚ಉظΛ଴ͨͣʹ௚ͪʹΠϝʔδΛೖΕସ͑Δ
    ςΟΞϦϯά͕ى͜ΔՄೳੑ͕͋Δ͕࠷΋ૣ͘ද͕ࣔߋ৽͞ΕΔ
    vk::PresentModeKHR::eMailbox
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͸ഁغ͞ΕΔ
    vk::PresentModeKHR::eFIFO
    ը໘ͷਨ௚ಉظΛ଴ͬͯΠϝʔδΛೖΕସ͑Δ
    ·ͩද͍ࣔͯ͠ͳ͍Πϝʔδ͕͋Δͷʹ࣍ͷΠϝʔδ͕དྷͨ৔߹
    ઌʹදࣔΩϡʔʹੵ·Ε͍ͯͨΠϝʔδ͔Βॱʹදࣔ͞ΕΔ

    View Slide

  45. .setPresentMode(vk::PresentModeKHR::eFifo)
    .setClipped(true)
    );
    swapchain_images=device.getSwapchainImagesKHR(swapchain);
    for(auto &swapchain_image:swapchain_images){
    swapchain_views.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo().setImage(swapchain_image)
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(format)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eColor,0,1,0,1
    ))
    )
    );
    }
    εϫοϓνΣΠϯͷΠϝʔδΛऔಘͯ͠
    ΠϝʔδϏϡʔΛ࡞͓ͬͯ͘
    ΠϝʔδϏϡʔͱ͸
    ը૾σʔλΛͲ͏ղऍ͢΂͖͔Λఆٛͨ͠΋ͷ
    Πϝʔδʹରͯ͠ಡΈॻ͖Λߦ͏ͷʹඞཁ
    εϫοϓνΣΠϯ

    View Slide

  46. Πϝʔδ
    (16ʹஔ͘σʔλͷ͏ͪ
    த਎ΛԿΒ͔ͷϑΥʔϚοτͷ
    ը૾σʔλͱͯ͠ղऍ͢Δ΋ͷ
    Πϝʔδ
    F4BNQMFE
    F4UPSBHF
    F$PMPS"UUBDINFOU
    F%FQUI4UFODJM"UUBDINFOU
    F*OQVU"UUBDINFOU
    ςΫενϟ
    γΣʔμ͔Β
    ೚ҙͷϐΫηϧΛ
    ಡΈॻ͖Ͱ͖Δը૾
    ϨϯμϦϯά݁Ռ
    ਂ౓όοϑΝ
    લͷαϒύε͔Βͷ
    ೖྗը૾
    ͜ΕΒ͸͍ͣΕ΋createImageͰ࡞ΕΔ
    FUD

    View Slide

  47. ϨϯμʔόοϑΝΛ࡞Δ
    εϫοϓνΣΠϯͷΠϝʔδ͸
    ΧϥʔόοϑΝ͚ͩͳͷͰ
    ਂ౓όοϑΝ΍ͦͷଞͷϨϯμϦϯάʹඞཁͳ
    Πϝʔδ͸ࣗ෼Ͱ༻ҙ͢Δඞཁ͕͋Δ

    View Slide

  48. ίϚϯυ
    ౤ೖ
    ϨϯμϦϯά
    ׬ྃ
    U U U U U
    දࣔ
    ྘ͱ੨͕ϨϯμϦϯάதͰ੺͕දࣔத
    εϫοϓνΣΠϯ͕ຕҎ্͋Δ৔߹
    ෳ਺ͷϨϯμϦϯά͕ಉ࣌ʹ૸͍ͬͯΔՄೳੑ͕͋Δ

    View Slide

  49. for(size_t i=0u;i!=swapchain_image_count;++i){
    depth_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setFormat(vk::Format::eD16Unorm)
    .setExtent({width,height,1})
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eDepthStencilAttachment|
    vk::ImageUsageFlagBits::eTransferDst
    )
    ));
    position_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setExtent(vk::Extent3D(width,height,1))
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setMipLevels(1)
    .setArrayLayers(1)
    ਂ౓όοϑΝ౳Ұ࣌తͳ஋Λஔ͘Πϝʔδ͸
    গͳ͘ͱ΋εϫοϓνΣΠϯͷຕ਺ຕඞཁ

    View Slide

  50. for(size_t i=0u;i!=swapchain_image_count;++i){
    depth_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setFormat(vk::Format::eD16Unorm)
    .setExtent({width,height,1})
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eDepthStencilAttachment|
    vk::ImageUsageFlagBits::eTransferDst
    )
    ));
    position_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setExtent(vk::Extent3D(width,height,1))
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eColorAttachment|
    vk::ImageUsageFlagBits::eTransferDst|
    ਂ౓όοϑΝ
    ઃఆ͸্͔Βॱʹ
    ࣍ݩΠϝʔδͰɺCJU੔਺ͷਂ౓஋ͷΈͰɺ
    େ͖͞͸ը໘αΠζͱಉ͡Ͱɺ.JQͳ͠ɺ
    ϨΠϠʔຕɺ༻్͸ਂ౓όοϑΝͱσʔλసૹઌ
    ϨϯμʔόοϑΝΛ࡞Δ

    View Slide

  51. vk::ImageUsageFlagBits::eSampled
    )
    ));
    position_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setExtent(vk::Extent3D(width,height,1))
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eColorAttachment|
    vk::ImageUsageFlagBits::eTransferDst|
    vk::ImageUsageFlagBits::eInputAttachment
    )
    ));
    normal_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setExtent(vk::Extent3D(width,height,1))
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eColorAttachment|
    ϫʔϧυ࠲ඪόοϑΝ༻ͷΠϝʔδΛ࡞Δ
    ઃఆ͸্͔Βॱʹ
    ࣍ݩΠϝʔδͰɺCJUුಈখ਺ͷ3(#"Ͱɺ
    େ͖͞͸ը໘αΠζͱಉ͡Ͱɺ.JQͳ͠ɺϨΠϠʔຕɺ
    ༻్͸ΧϥʔόοϑΝͱσʔλసૹઌͱ*OQVU"UUBDINFOU
    ϫʔϧυ࠲ඪόοϑΝ

    View Slide

  52. vk::ImageUsageFlagBits::eInputAttachment
    )
    ));
    normal_image.emplace_back(device.createImage(
    vk::ImageCreateInfo()
    .setImageType(vk::ImageType::e2D)
    .setExtent(vk::Extent3D(width,height,1))
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setMipLevels(1)
    .setArrayLayers(1)
    .setUsage(
    vk::ImageUsageFlagBits::eColorAttachment|
    vk::ImageUsageFlagBits::eTransferDst|
    vk::ImageUsageFlagBits::eInputAttachment
    )
    ));
    }
    ϫʔϧυ๏ઢόοϑΝ༻ͷΠϝʔδΛ࡞Δ
    ઃఆ͸্͔Βॱʹ
    ࣍ݩΠϝʔδͰɺCJUුಈখ਺ͷ3(#"Ͱɺ
    େ͖͞͸ը໘αΠζͱಉ͡Ͱɺ.JQͳ͠ɺϨΠϠʔຕɺ
    ༻్͸ΧϥʔόοϑΝͱσʔλసૹઌͱ*OQVU"UUBDINFOU
    ϫʔϧυ๏ઢόοϑΝ

    View Slide

  53. for(size_t i=0u;i!=swapchain_image_count;++i){
    const auto depth_memory_requirements=
    device.getImageMemoryRequirements(depth_image[i]);
    if(total_image_memory%depth_memory_requirements.alignment)
    total_image_memory+=
    depth_memory_requirements.alignment
    -(total_image_memory%depth_memory_requirements.alignment);
    depth_memory_offsets.emplace_back(
    total_image_memory,depth_memory_requirements.size
    );
    total_image_memory+=depth_memory_requirements.size;
    const auto position_memory_requirements=
    device.getImageMemoryRequirements(position_image[i]);
    if(total_image_memory%position_memory_requirements.alignment)
    total_image_memory+=
    position_memory_requirements.alignment
    -(
    total_image_memory%
    position_memory_requirements.alignment
    );
    createImage͸࣮ࡍͷσʔλ͕ஔ͔ΕΔ
    ϝϞϦྖҬΛ֬อ͸͠ͳ͍
    ֤Πϝʔδʹඞཁͳ
    ϝϞϦͷαΠζͱΞϥΠϯϝϯτΛऔಘͯ͠

    View Slide

  54. const auto required_memory_props=
    vk::MemoryPropertyFlagBits::eDeviceLocal;
    const auto memory_type_index=
    std::distance(
    memory_properties.memoryTypes,
    std::find_if(
    memory_properties.memoryTypes,
    memory_properties.memoryTypes + VK_MAX_MEMORY_TYPES,
    [&](const auto &v){
    return (v.propertyFlags&required_memory_props)==
    required_memory_props;
    }
    )
    );
    image_memory=device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(total_image_memory)
    .setMemoryTypeIndex(memory_type_index)
    );
    allocateMemoryͰඞཁͳϝϞϦྖҬΛ֬อ
    σόΠεͰ࢖͑ΔϝϞϦͷத͔Β
    Α͛͞ͳϝϞϦΛબΜͰ

    View Slide

  55. ϝϞϦͷछྨ
    MemoryPropertyFlagBits::eDeviceLocal
    ͜ͷϝϞϦ͸GPU͔ΒΞΫηε͢Δͷʹ࠷΋దͨ͠ϝϞϦͰ͋Δ
    MemoryPropertyFlagBits::eHostVisible
    ͜ͷϝϞϦ͸$16ଆ͔Βݟ͑Δ
    MemoryPropertyFlagBits::eHostCoherent
    ͜ͷϝϞϦʹର͢ΔಡΈॻ͖͸CPUͱGPUͰΩϟογϡҰ؏ੑ͕อͨΕΔ
    MemoryPropertyFlagBits::eHostCached
    ͜ͷϝϞϦʹର͢ΔಡΈॻ͖ΛCPU͸Ωϟογϡ͢Δ
    MemoryPropertyFlagBits::eLazilyAllocated
    ͜ͷϝϞϦ͸ඞཁʹͳΔ·Ͱϖʔδׂ͕Γ౰ͯΒΕͳ͍
    γεςϜʹ͸ৼΔ෣͍͕ҟͳΔෳ਺छྨͷ
    ϝϞϦ͕උΘ͍ͬͯΔ͜ͱ͕͋Δ
    ༻్ʹԠͯ͡Ͳ͜ʹσʔλΛஔ͔͘બͿ

    View Slide

  56. for(size_t i=0u; i!=swapchain_image_count;++i){
    device.bindImageMemory(
    depth_image[i],image_memory,depth_memory_offsets[i].first
    );
    device.bindImageMemory(
    position_image[i],image_memory,
    position_memory_offsets[i].first
    );
    device.bindImageMemory(
    normal_image[i],image_memory,
    normal_memory_offsets[ i ].first
    );
    depth_view.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo()
    .setImage(depth_image[i])
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(vk::Format::eD16Unorm)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eDepth,0,1,0,1
    ))
    ));
    ֬อͨ͠ϝϞϦΛ*NBHFʹCJOEͯ͠
    ϑϨʔϜόοϑΝΛ࡞Δ

    View Slide

  57. normal_image[i],image_memory,
    normal_memory_offsets[ i ].first
    );
    depth_view.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo()
    .setImage(depth_image[i])
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(vk::Format::eD16Unorm)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eDepth,0,1,0,1
    ))
    ));
    position_view.emplace_back(device.createImageView(
    vk::ImageViewCreateInfo()
    .setImage(position_image[i])
    .setViewType(vk::ImageViewType::e2D)
    .setFormat(vk::Format::eR32G32B32A32Sfloat)
    .setSubresourceRange(vk::ImageSubresourceRange(
    vk::ImageAspectFlagBits::eColor,0,1,0,1
    ))
    ));
    normal_view.emplace_back( device.createImageView(
    vk::ImageViewCreateInfo()
    .setImage( normal_image[ i ] )
    .setViewType( vk::ImageViewType::e2D )
    ΠϝʔδϏϡʔΛ࡞͓ͬͯ͘
    ϑϨʔϜόοϑΝΛ࡞Δ
    ༁͜ͷྖҬ͸CJUුಈখ਺3(#"ͷ࣍ݩը૾ͱͯ͠࢖ͬͯͶ
    ༁͜ͷྖҬ͸CJU੔਺ਂ౓ͷΈͷ࣍ݩը૾ͱͯ͠࢖ͬͯͶ

    View Slide

  58. framebuffers.emplace_back(device.createFramebuffer(
    vk::FramebufferCreateInfo()
    .setRenderPass(render_pass)
    .setAttachmentCount(attachments.size())
    .setPAttachments(attachments.data())
    .setWidth(width)
    .setHeight(height)
    .setLayers(1)
    ) );
    *NBHF7JFXͷ഑ྻͱ
    ͍ͩͿޙͷํͰ࡞Δ
    *NBHF7JFXͷ࢖͍ํΛઃఆͨ͠ϨϯμʔύεΛ
    ૊Έ߹ΘͤͯϑϨʔϜόοϑΝ͕׬੒͢Δ
    ϑϨʔϜόοϑΝΛ࡞Δ
    ͜Ε

    View Slide

  59. ςΫενϟͷσʔλΛॻ͖ࠐΉʹ͸
    Πϝʔδʹ$16ଆ͔Βॻ͖ࠐΉඞཁ͕͋Δ
    ςΫενϟ
    ςΫενϟΛஔ͍ͨϝϞϦ͕eHostVisibleͳ৔߹
    vk::Device::mapMemoryͰ
    $16ଆͷΞυϨεۭؒʹϚοϓͯ͠memcpy
    ςΫενϟΛஔ͍ͨϝϞϦ͕eHostVisibleͰͳ͍৔߹
    Ұ౓eHostVisibleͳϝϞϦʹΠϝʔδΛ࡞ͬͯ
    ্ͷํ๏ͰσʔλΛॻ͘
    vk::CommandBuffer::copyImageΛ
    ΩϡʔʹੵΜͰ(16ʹσʔλΛίϐʔͤ͞Δ

    View Slide

  60. ίϚϯυόοϑΝ
    ίϚϯυόοϑΝ
    ඳըͯ͠
    ύΠϓϥΠϯมߋ
    σʔλసૹͯ͠
    ׬ྃ଴ͬͯ
    σόΠε
    Ωϡʔ
    (16΁ͷίϚϯυ͸
    ·ͣίϚϯυόοϑΝʹੵΉ
    ͜ͷ࣌఺ͰίϚϯυ͸
    (16Ͱͷ۩ମతͳॲཧʹ
    ຋༁͞ΕΔ
    ࣮ߦ
    ίϚϯυόοϑΝ୯ҐͰ
    ΩϡʔʹίϚϯυΛੵΉ
    ίϚϯυόοϑΝ͸Կ౓Ͱ΋ΩϡʔʹੵΊΔ
    ຖϑϨʔϜߦ͏ॲཧͷίϚϯυྻΛ
    ຖϑϨʔϜͭͮͭ౤͛Δඞཁ͸ͳ͍

    View Slide

  61. ίϚϯυόοϑΝ
    ίϚϯυόοϑΝ
    ඳըͯ͠
    ύΠϓϥΠϯมߋ
    σʔλసૹͯ͠
    σόΠε
    Ωϡʔ
    ࣮ߦ
    ίϚϯυόοϑΝ
    ඳըͯ͠
    ύΠϓϥΠϯมߋ
    σʔλసૹͯ͠
    εϨου εϨου
    ίϚϯυόοϑΝ͸ෳ਺ͷεϨουͰ࡞ͬͯ
    ͭͷΩϡʔʹੵΜͰ΋ྑ͍

    View Slide

  62. command_pool=device.createCommandPool(
    vk::CommandPoolCreateInfo()
    .setQueueFamilyIndex(graphics_queue_index)
    );
    command_buffer=device.allocateCommandBuffers(
    vk::CommandBufferAllocateInfo()
    .setCommandPool(command_pool)
    .setLevel(vk::CommandBufferLevel::ePrimary)
    .setCommandBufferCount(swapchain_image_count)
    );
    ίϚϯυόοϑΝΛ࡞Δ

    View Slide

  63. όοϑΝ
    (16ʹஔ͘σʔλͷ͏ͪ
    த਎Λը૾σʔλͱͯ͠ղऍ͠ͳ͍΋ͷ
    όοϑΝ
    F6OJGPSN#V⒎FS
    F4UPSBHF5FYFM#V⒎FS
    F7FSUFY#V⒎FS
    F*OEFY#V⒎FS
    F4UPSBHF#V⒎FS
    γΣʔμͷ
    VOJGPSN஋
    ΠϝʔδόοϑΝ
    ௖఺όοϑΝ
    ௖఺
    ΠϯσοΫε
    γΣʔμετϨʔδ
    όοϑΝ
    ͜ΕΒ͸͍ͣΕ΋createBufferͰ࡞ΕΔ
    FUD

    View Slide

  64. vertex_buffer=device.createBuffer(
    vk::BufferCreateInfo()
    .setSize(sizeof(vertex_t)*scene_.get_vertices().size())
    .setUsage(
    vk::BufferUsageFlagBits::eVertexBuffer|
    vk::BufferUsageFlagBits::eTransferDst
    )
    );
    vertex_memory=device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(vertex_memory_requirements.size)
    .setMemoryTypeIndex(memory_type_index)
    );
    device.bindBufferMemory(vertex_buffer,vertex_memory,0);
    std::shared_ptr mapped_memory(
    static_cast(device.mapMemory(
    vertex_memory,0,vertex_memory_requirements.size
    )), [&](uint8_t *p){if(p)device.unmapMemory(vertex_memory);}
    );
    memcpy(
    mapped_memory.get(),scene_.get_vertices().data(),
    sizeof(vertex_t)*scene_.get_vertices().size()
    ௖఺όοϑΝ
    ༻్F7FSUFY#V⒎FSͰόοϑΝΛ࡞੒
    ࣍ݩܗঢ়ͷ৘ใ

    View Slide

  65. vertex_buffer=device.createBuffer(
    vk::BufferCreateInfo()
    .setSize(sizeof(vertex_t)*scene_.get_vertices().size())
    .setUsage(
    vk::BufferUsageFlagBits::eVertexBuffer|
    vk::BufferUsageFlagBits::eTransferDst
    )
    );
    vertex_memory=device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(vertex_memory_requirements.size)
    .setMemoryTypeIndex(memory_type_index)
    );
    device.bindBufferMemory(vertex_buffer,vertex_memory,0);
    std::shared_ptr mapped_memory(
    static_cast(device.mapMemory(
    vertex_memory,0,vertex_memory_requirements.size
    )), [&](uint8_t *p){if(p)device.unmapMemory(vertex_memory);}
    );
    memcpy(
    mapped_memory.get(),scene_.get_vertices().data(),
    sizeof(vertex_t)*scene_.get_vertices().size()
    ௖఺όοϑΝ
    Πϝʔδಉ༷࣮ࡍͷϝϞϦྖҬ͸ࣗ෼Ͱ֬อ

    View Slide

  66. vertex_buffer=device.createBuffer(
    vk::BufferCreateInfo()
    .setSize(sizeof(vertex_t)*scene_.get_vertices().size())
    .setUsage(
    vk::BufferUsageFlagBits::eVertexBuffer|
    vk::BufferUsageFlagBits::eTransferDst
    )
    );
    vertex_memory=device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(vertex_memory_requirements.size)
    .setMemoryTypeIndex(memory_type_index)
    );
    device.bindBufferMemory(vertex_buffer,vertex_memory,0);
    std::shared_ptr mapped_memory(
    static_cast(device.mapMemory(
    vertex_memory,0,vertex_memory_requirements.size
    )), [&](uint8_t *p){if(p)device.unmapMemory(vertex_memory);}
    );
    memcpy(
    mapped_memory.get(),scene_.get_vertices().data(),
    sizeof(vertex_t)*scene_.get_vertices().size()
    );
    ௖఺όοϑΝ
    సૹํ๏΋Πϝʔδͱಉ͡
    $16ͷϝϞϦۭؒʹϚοϓͯ͠ίϐʔ

    View Slide

  67. const auto vertex_input_binding=
    vk::VertexInputBindingDescription()
    .setBinding(0)
    .setStride(sizeof(vertex_t))
    .setInputRate(vk::VertexInputRate::eVertex);
    const std::vector
    vertex_input_attribute{
    vk::VertexInputAttributeDescription()
    .setLocation(0)
    .setBinding(0)
    .setFormat(vk::Format::eR32G32B32Sfloat)
    .setOffset(offsetof(vertex_t,position)),
    vk::VertexInputAttributeDescription()
    .setLocation(1)
    .setBinding(0)
    .setFormat(vk::Format::eR32G32B32Sfloat)
    .setOffset(offsetof(vertex_t,color)),
    vk::VertexInputAttributeDescription()
    .setLocation(2)
    .setBinding(0)
    .setFormat(vk::Format::eR32G32B32Sfloat)
    .setOffset(offsetof(vertex_t,normal)),
    ௖఺όοϑΝ
    ͜ͷ௖఺όοϑΝʹ
    ௖఺͕ͲͷΑ͏ʹ֨ೲ͞Ε͍ͯΔ͔Λද͢
    vk::PipelineVertexInputStateCreateInfo
    Λ࡞͓ͬͯ͘
    ௖఺ݸͷαΠζ
    ௖఺γΣʔμͷԿ൪໨ͷ௖఺ଐੑʹ
    ରԠ͚ͮΔ͔
    CJUුಈখ਺͔ͭΒͳΔϕΫτϧ஋
    ௖఺ͷઌ಄͔ΒԿόΠτ໨ʹஔ͔Ε͍ͯΔ͔

    View Slide

  68. uniform_buffer=device.createBuffer(
    vk::BufferCreateInfo()
    .setSize(sizeof(glm::mat4)*scene_.get_matrices().size())
    .setUsage(
    vk::BufferUsageFlagBits::eUniformBuffer|
    vk::BufferUsageFlagBits::eTransferDst
    )
    );
    uniform_memory = device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(uniform_memory_requirements.size)
    .setMemoryTypeIndex(memory_type_index)
    );
    device.bindBufferMemory(uniform_buffer,uniform_memory,0);
    std::shared_ptr mapped_memory(
    static_cast(device.mapMemory(
    uniform_memory,0,uniform_memory_requirements.size
    )),[&](uint8_t *p){if(p)device.unmapMemory(uniform_memory);}
    );
    memcpy(
    mapped_memory.get(), scene_.get_matrices().data(),
    sizeof(glm::mat4)*scene_.get_matrices().size()
    ϢχϑΥʔϜόοϑΝ
    γΣʔμ͕࣮ߦதʹΞΫηεͰ͖Δఆ਺
    ༻్F6OJGPSN#V⒎FSͰόοϑΝΛ࡞੒

    View Slide

  69. uniform_buffer=device.createBuffer(
    vk::BufferCreateInfo()
    .setSize(sizeof(glm::mat4)*scene_.get_matrices().size())
    .setUsage(
    vk::BufferUsageFlagBits::eUniformBuffer|
    vk::BufferUsageFlagBits::eTransferDst
    )
    );
    uniform_memory = device.allocateMemory(
    vk::MemoryAllocateInfo()
    .setAllocationSize(uniform_memory_requirements.size)
    .setMemoryTypeIndex(memory_type_index)
    );
    device.bindBufferMemory(uniform_buffer,uniform_memory,0);
    std::shared_ptr mapped_memory(
    static_cast(device.mapMemory(
    uniform_memory,0,uniform_memory_requirements.size
    )),[&](uint8_t *p){if(p)device.unmapMemory(uniform_memory);}
    );
    memcpy(
    mapped_memory.get(), scene_.get_matrices().data(),
    sizeof(glm::mat4)*scene_.get_matrices().size()
    );
    ϢχϑΥʔϜόοϑΝ
    ޙͷखॱ͸௖఺όοϑΝͱҰॹ

    View Slide

  70. std::fstream file("vert.spv",std::ios::in|std::ios::binary);
    const std::vector bin(
    (std::istreambuf_iterator(file)),
    std::istreambuf_iterator()
    );
    mesh_pass_vertex_shader_module=device.createShaderModule(
    vk::ShaderModuleCreateInfo()
    .setCodeSize(bin.size())
    .setPCode(reinterpret_cast(bin.data()))
    );
    γΣʔμϞδϡʔϧ
    ύΠϓϥΠϯͷ೚ҙͷܭࢉ͕Ͱ͖Δ෦෼Ͱ࣮ߦ͢Δίʔυ
    Ͱ͸GLSLͱݺ͹ΕΔߴڃݴޠͷιʔεΛ౉ͯ͠
    ࣮ߦ࣌ʹίϯύΠϧ͍͕ͯͨ͠
    Ͱ͸SPIR-Vͱݺ͹ΕΔίϯύΠϧࡁΈͷ
    தؒݴޠͷΧλϚϦΛ౉ͯ͠γΣʔμϞδϡʔϧΛ࡞Δ
    γΣʔμ͸41*37Ͱు͔Ε͍ͯ͑͞Ε͹ԿݴޠͰॻ͍ͯ΋ྑ͍

    View Slide

  71. γΣʔμϞδϡʔϧ
    https://github.com/thewilsonator/llvm-target-spirv
    ࠷ۙ
    --7.*3Λ41*37ʹίϯύΠϧ͢ΔόοΫΤϯυ
    ͷ։ൃ͕࢝·ͬͨ

    View Slide

  72. ϝϞϦ
    σεΫϦϓληοτ
    ύΠϓϥΠϯͱ࣮ࡍͷσʔλͷؒʹڬ·ͬͯ
    ͲͷσʔλΛ࢖ͬͯϨϯμϦϯά͢Δ͔
    Λ੾Γସ͑ΔτϥϯϙϦϯͷΑ͏ͳ΋ͷ
    Πϝʔδ
    Πϝʔδ
    ௖఺όοϑΝ
    ϢχϑΥʔϜ
    όοϑΝ
    ετϨʔδ
    όοϑΝ
    σεΫϦϓλ
    ηοτ
    σεΫϦϓλ
    ηοτ
    ύΠϓϥΠϯ
    ຕ໨ͷ
    ςΫενϟ͍ͩ͘͞
    ຕ໨ͷ
    ςΫενϟ͍ͩ͘͞

    View Slide

  73. const std::array types{
    vk::DescriptorPoolSize()
    .setType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1),
    vk::DescriptorPoolSize()
    .setType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(2)
    };
    descriptor_pool=device.createDescriptorPool(
    vk::DescriptorPoolCreateInfo()
    .setPoolSizeCount(types.size())
    .setPPoolSizes(types.data())
    .setMaxSets(100)
    );
    const std::array
    descriptor_set_layout_bindings{
    vk::DescriptorSetLayoutBinding()
    σεΫϦϓληοτΛ࡞Δ
    σεΫϦϓλ༻ͷϝϞϦϓʔϧΛ࡞੒

    View Slide

  74. .setPPoolSizes(types.data())
    .setMaxSets(100)
    );
    const std::array
    descriptor_set_layout_bindings{
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1)
    .setBinding(0)
    .setStageFlags(vk::ShaderStageFlagBits::eVertex)
    .setPImmutableSamplers(nullptr),
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(1)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr),
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(2)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr)
    };
    const std::vector
    σεΫϦϓληοτΛ࡞Δ
    ༁௖఺γΣʔμͰಡΊΔϢχϑΥʔϜόοϑΝΛ
    CJOEJOHʹׂΓ౰ͯ

    View Slide

  75. .setPPoolSizes(types.data())
    .setMaxSets(100)
    );
    const std::array
    descriptor_set_layout_bindings{
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1)
    .setBinding(0)
    .setStageFlags(vk::ShaderStageFlagBits::eVertex)
    .setPImmutableSamplers(nullptr),
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(1)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr),
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(2)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr)
    };
    const std::vector
    σεΫϦϓληοτΛ࡞Δ
    ༁ϑϥάϝϯτγΣʔμͰಡΊΔೖྗΞλονϝϯτΛ
    CJOEJOHʹׂΓ౰ͯ

    View Slide

  76. vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(1)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr),
    vk::DescriptorSetLayoutBinding()
    .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(2)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr)
    };
    const std::vector
    descriptor_set_layout{
    device.createDescriptorSetLayout(
    vk::DescriptorSetLayoutCreateInfo()
    .setBindingCount( descriptor_set_layout_bindings.size() )
    .setPBindings( descriptor_set_layout_bindings.data() ),
    nullptr
    )
    };
    ༁ϑϥάϝϯτγΣʔμͰಡΊΔೖྗΞλονϝϯτΛ
    CJOEJOHʹׂΓ౰ͯ
    layout(input_attachment_index=0,set=0,binding=1)
    uniform subpassInput position;
    layout(input_attachment_index=1,set=0,binding=2)
    uniform subpassInput normal;
    void main() {
    vec3 pos=subpassLoad(position).xyz;
    vec3 N=subpassLoad(normal).xyz;
    vec3 V=normalize(eye-pos);
    vec3 L=normalize(lightpos-pos);
    ͜ͷೖྗΞλονϝϯτ͸γΣʔμͰ͸
    positionͱ͍͏໊લͰΞΫηεͰ͖ΔΑ͏ʹͳΔ
    GLSL

    View Slide

  77. .setDescriptorType(vk::DescriptorType::eInputAttachment)
    .setDescriptorCount(1)
    .setBinding(2)
    .setStageFlags(vk::ShaderStageFlagBits::eFragment)
    .setPImmutableSamplers(nullptr)
    };
    const std::vector
    descriptor_set_layout{
    device.createDescriptorSetLayout(
    vk::DescriptorSetLayoutCreateInfo()
    .setBindingCount( descriptor_set_layout_bindings.size() )
    .setPBindings( descriptor_set_layout_bindings.data() ),
    nullptr
    )
    };
    σεΫϦϓληοτΛ࡞Δ
    σεΫϦϓληοτͷͲ͜ʹ
    Կͷ৘ใ͕ஔ͔Ε͍ͯΔ͔Λද͢
    σεΫϦϓληοτϨΠΞ΢τΛ࡞Δ

    View Slide

  78. const auto descriptor_set_=device.allocateDescriptorSets(
    vk::DescriptorSetAllocateInfo()
    .setDescriptorPool(descriptor_pool)
    .setDescriptorSetCount(descriptor_set_layout.size())
    .setPSetLayouts(descriptor_set_layout.data())
    );
    const std::vector image_descriptors{
    vk::DescriptorImageInfo()
    .setImageView(position_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal),
    vk::DescriptorImageInfo()
    .setImageView(normal_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
    };
    const std::vector write_descriptor_set{
    vk::WriteDescriptorSet()
    .setDstSet(descriptor_set_[0])
    .setDescriptorType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1)
    .setPBufferInfo( &uniform_buffer_info )
    .setDstBinding( 0 ),
    // (ུ)
    σεΫϦϓληοτΛ࡞Δ
    σεΫϦϓληοτʹඞཁͳྖҬΛׂΓ౰ͯΔ

    View Slide

  79. .setDescriptorSetCount(descriptor_set_layout.size())
    .setPSetLayouts(descriptor_set_layout.data())
    );
    const std::vector image_descriptors{
    vk::DescriptorImageInfo()
    .setImageView(position_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal),
    vk::DescriptorImageInfo()
    .setImageView(normal_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
    };
    const std::vector write_descriptor_set{
    vk::WriteDescriptorSet()
    .setDstSet(descriptor_set_[0])
    .setDescriptorType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1)
    .setPBufferInfo( &uniform_buffer_info )
    .setDstBinding( 0 ),
    // (ུ)
    };
    device.updateDescriptorSets( write_descriptor_set, nullptr );
    descriptor_set.emplace_back( std::move( descriptor_set_ ) );
    σεΫϦϓληοτΛ࡞Δ
    ࢖༻͢ΔΠϝʔδͱόοϑΝΛྻڍ͢Δ

    View Slide

  80. .setDescriptorSetCount(descriptor_set_layout.size())
    .setPSetLayouts(descriptor_set_layout.data())
    );
    const std::vector image_descriptors{
    vk::DescriptorImageInfo()
    .setImageView(position_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal),
    vk::DescriptorImageInfo()
    .setImageView(normal_view[i])
    .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
    };
    const std::vector write_descriptor_set{
    vk::WriteDescriptorSet()
    .setDstSet(descriptor_set_[0])
    .setDescriptorType(vk::DescriptorType::eUniformBuffer)
    .setDescriptorCount(1)
    .setPBufferInfo( &uniform_buffer_info )
    .setDstBinding( 0 ),
    // (ུ)
    };
    device.updateDescriptorSets( write_descriptor_set, nullptr );
    descriptor_set.emplace_back( std::move( descriptor_set_ ) );
    σεΫϦϓληοτΛ࡞Δ
    σεΫϦϓληοτͷ஋Λߋ৽

    View Slide

  81. ϨϯμʔύεΛ࡞Δ
    αϒύεͱ͸
    Ϩϯμʔύεʹؚ·ΕΔ৘ใ
    ύΠϓϥΠϯͷ্͔ΒԼ·Ͱ
    ճ෼
    ϨϯμϦϯά͕͍ͭ͘ͷαϒύεͰߏ੒͞Ε͍ͯΔ͔
    αϒύε͕ͲΜͳೖྗΛड͚औͬͯͲΜͳग़ྗΛు͔͘
    Ͳͷαϒύε͕ͲͷαϒύεͷޙͰ
    ࣮ߦ͞ΕΔඞཁ͕͋Δ͔

    View Slide

  82. Ξλονϝϯτ
    ύε
    ύε
    ύε
    Πϝʔδ
    Πϝʔδ
    Πϝʔδ
    Πϝʔδ
    αϒύεʹग़ೖΓ͢ΔΠϝʔδΛΞλονϝϯτͱݺͿ

    View Slide

  83. const std::vector attachments{
    vk::AttachmentDescription()
    .setFormat(vk::Format::eR32G32B32Sfloat)
    .setSamples(vk::SampleCountFlagBits::e1)
    .setLoadOp(vk::AttachmentLoadOp::eClear)
    .setStoreOp(vk::AttachmentStoreOp::eStore)
    .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
    .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
    .setInitialLayout(vk::ImageLayout::eColorAttachmentOptimal)
    .setFinalLayout( vk::ImageLayout::eShaderReadOnlyOptimal),
    // (ུ)
    };
    const std::array
    mesh_pass_color_reference{
    vk::AttachmentReference()
    .setAttachment(0)
    .setLayout(vk::ImageLayout::eColorAttachmentOptimal),
    vk::AttachmentReference()
    .setAttachment(1)
    .setLayout(vk::ImageLayout::eColorAttachmentOptimal)
    };
    const std::array
    ϨϯμʔύεΛ࡞Δ
    Ϩϯμʔύεʹొ৔͢ΔΞλονϝϯτΛఆٛ

    View Slide

  84. const std::array
    mesh_pass_depth_reference{
    // (ུ)
    const std::vector subpass{
    vk::SubpassDescription()
    .setPipelineBindPoint( vk::PipelineBindPoint::eGraphics )
    .setInputAttachmentCount( 0 )
    .setPInputAttachments( nullptr )
    .setColorAttachmentCount( mesh_pass_color_reference.size() )
    .setPColorAttachments( mesh_pass_color_reference.data() )
    .setPResolveAttachments( nullptr )
    .setPDepthStencilAttachment( &mesh_pass_depth_reference )
    .setPreserveAttachmentCount( 0 )
    .setPPreserveAttachments( nullptr ),
    // (ུ)
    };
    ϨϯμʔύεΛ࡞Δ
    ࢖༻͢ΔΞλονϝϯτΛࢦఆͯ͠
    αϒύεΛఆٛ

    View Slide

  85. std::array subpass_dependency{
    vk::SubpassDependency()
    .setSrcSubpass( 0 )
    .setDstSubpass( 1 )
    .setSrcStageMask(
    vk::PipelineStageFlagBits::eColorAttachmentOutput
    )
    .setDstStageMask(vk::PipelineStageFlagBits::eFragmentShader)
    .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
    .setDstAccessMask(vk::AccessFlagBits::eInputAttachmentRead)
    };
    ϨϯμʔύεΛ࡞Δ
    ༁αϒύεͷϑϥάϝϯτγΣʔμ͸
    αϒύεͷΧϥʔΞλονϝϯτ΁ͷग़ྗ͕
    ׬ྃͨ͠ޙʹ࣮ߦ͞Εͳ͚Ε͹ͳΒͳ͍
    αϒύεͰΧϥʔΞλονϝϯτͩͬͨ΋ͷ͕
    αϒύεͰೖྗΞλονϝϯτͱͯ͠࢖ΘΕΔ

    View Slide

  86. ௖఺γΣʔμ
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ϑϥάϝϯτγΣʔμ
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽
    δΦϝτϦγΣʔμ
    ςηϨʔγϣϯ੍ޚγΣʔμ
    ςηϨʔγϣϯධՁγΣʔμ
    Ͱ͔͍ϓϦϛςΟϒΛ෼ׂ
    ௖఺γΣʔμ
    ը໘͔Β͸Έग़͢ࡾ֯ܗΛࣺͯΔ
    ࡾ֯ܗͷ಺ଆͷϐΫηϧΛٻΊΔ
    ϑϥάϝϯτγΣʔμ
    طʹඳ͔Εͨ෺ΑΓखલ͔֬ೝ
    ϑϨʔϜόοϑΝͷ৭Λߋ৽
    δΦϝτϦγΣʔμ
    ςηϨʔγϣϯ੍ޚγΣʔμ
    ςηϨʔγϣϯධՁγΣʔμ
    Ͱ͔͍ϓϦϛςΟϒΛ෼ׂ
    ಉظ
    αϒύε αϒύε

    View Slide

  87. ύΠϓϥΠϯ
    ࢖༻͢ΔγΣʔμϞδϡʔϧ
    ௖఺ΛϓϦϛςΟϒʹ͢Δํ๏
    Ϗϡʔϙʔτͱγβʔ
    ϥελϥΠβͷڍಈ
    .4""ͷઃఆ
    εςϯγϧͷઃఆ
    ਂ౓ςετͷઃఆ
    ΧϥʔϒϨϯυͷϚεΫ
    άϥϑΟοΫύΠϓϥΠϯʹؚ·ΕΔ৘ใ

    View Slide

  88. ύΠϓϥΠϯ
    ࠓճ͸ར༻͠ͳ͍͕
    γΣʔμʹΑΔܭࢉ͚͕ͩՄೳͰ
    άϥϑΟοΫʹؔ͢Δػೳ͕Ұ੾ͳ͍
    ίϯϐϡʔτύΠϓϥΠϯ
    ΋༻ҙ͞Ε͍ͯΔ
    Λ$6%"ͷΑ͏ʹ࢖͍͍ͨ৔߹
    ඞཁͳઃఆ͕গͳ͍ͷͰͪ͜Βͷํָ͕

    View Slide

  89. pipeline_cache=
    device.createPipelineCache(vk::PipelineCacheCreateInfo());
    const std::array
    mesh_pass_pipeline_shader_stages{
    vk::PipelineShaderStageCreateInfo()
    .setStage(vk::ShaderStageFlagBits::eVertex)
    .setModule(mesh_pass_vertex_shader_module)
    .setPName(“main"),
    // (ུ)
    };
    auto const input_assembly_info=
    vk::PipelineInputAssemblyStateCreateInfo()
    .setTopology(vk::PrimitiveTopology::eTriangleList);
    auto const viewport_info=
    vk::PipelineViewportStateCreateInfo()
    .setViewportCount(1)
    .setScissorCount(1);
    auto const rasterization_info=
    vk::PipelineRasterizationStateCreateInfo()
    .setDepthClampEnable(VK_FALSE)
    ύΠϓϥΠϯΛ࡞Δ

    View Slide

  90. .setAttachmentCount(mesh_color_blend_attachments.size())
    .setPAttachments(mesh_color_blend_attachments.data());
    const std::array
    ɹpost_color_blend_attachments{
    vk::PipelineColorBlendAttachmentState()
    .setColorWriteMask(
    ɹ vk::ColorComponentFlagBits::eR|
    vk::ColorComponentFlagBits::eG|
    vk::ColorComponentFlagBits::eB|
    vk::ColorComponentFlagBits::eA
    )
    };
    const auto post_color_blend_info=
    vk::PipelineColorBlendStateCreateInfo()
    .setAttachmentCount(post_color_blend_attachments.size())
    .setPAttachments(post_color_blend_attachments.data());
    const std::array dynamic_states{
    vk::DynamicState::eViewport,
    vk::DynamicState::eScissor
    };
    const auto dynamic_state_info=
    vk::PipelineDynamicStateCreateInfo()
    .setDynamicStateCount(dynamic_states.size())
    .setPDynamicStates(dynamic_states.data());
    ύΠϓϥΠϯΛ࡞Δ

    View Slide

  91. ύΠϓϥΠϯΛ࡞Δ
    const std::array
    pipeline_create_info{
    vk::GraphicsPipelineCreateInfo()
    .setStageCount(mesh_pass_pipeline_shader_stages.size())
    .setPStages(mesh_pass_pipeline_shader_stages.data())
    .setPVertexInputState(&vertex_input_state)
    .setPInputAssemblyState(&input_assembly_info)
    .setPViewportState(&viewport_info)
    .setPRasterizationState(&rasterization_info)
    .setPMultisampleState(&multisample_info)
    .setPDepthStencilState(&depth_stencil_info)
    .setPColorBlendState(&mesh_color_blend_info)
    .setPDynamicState(&dynamic_state_info)
    .setLayout(pipeline_layout)
    .setRenderPass(render_pass)
    .setSubpass(0),
    // (ུ)
    };
    graphics_pipeline=device.createGraphicsPipelines(
    pipeline_cache,pipeline_create_info
    );

    View Slide

  92. const std::array clear_values{
    vk::ClearColorValue(
    std::array({{0.0f,0.0f,0.0f,1.0f}})
    ),
    // (ུ)
    };
    command_buffer[i].begin(
    vk::CommandBufferBeginInfo()
    .setFlags(
    vk::CommandBufferUsageFlagBits::eSimultaneousUse
    )
    );
    auto const pass_info=
    vk::RenderPassBeginInfo()
    .setRenderPass(render_pass)
    .setFramebuffer(framebuffers[i])
    .setRenderArea(vk::Rect2D(
    vk::Offset2D(0,0),vk::Extent2D(width,height))
    )
    .setClearValueCount(clear_values.size())
    .setPClearValues(clear_values.data());
    ίϚϯυΛه࿥͢Δ
    ίϚϯυͷه࿥Λ։࢝

    View Slide

  93. vk::CommandBufferUsageFlagBits::eSimultaneousUse
    )
    );
    auto const pass_info=
    vk::RenderPassBeginInfo()
    .setRenderPass(render_pass)
    .setFramebuffer(framebuffers[i])
    .setRenderArea(vk::Rect2D(
    vk::Offset2D(0,0),vk::Extent2D(width,height))
    )
    .setClearValueCount(clear_values.size())
    .setPClearValues(clear_values.data());
    command_buffer[i].beginRenderPass(
    &pass_info,vk::SubpassContents::eInline
    );
    command_buffer[i].bindPipeline(
    vk::PipelineBindPoint::eGraphics,graphics_pipeline[0]
    );
    std::vector ds_offset{0};
    command_buffer[i].bindDescriptorSets(
    vk::PipelineBindPoint::eGraphics,pipeline_layout,0,
    descriptor_set[ i ], ds_offset
    );
    ίϚϯυΛه࿥͢Δ
    ϨϯμʔύεΛ։࢝

    View Slide

  94. .setFramebuffer(framebuffers[i])
    .setRenderArea(vk::Rect2D(
    vk::Offset2D(0,0),vk::Extent2D(width,height))
    )
    .setClearValueCount(clear_values.size())
    .setPClearValues(clear_values.data());
    command_buffer[i].beginRenderPass(
    &pass_info,vk::SubpassContents::eInline
    );
    command_buffer[i].bindPipeline(
    vk::PipelineBindPoint::eGraphics,graphics_pipeline[0]
    );
    std::vector ds_offset{0};
    command_buffer[i].bindDescriptorSets(
    vk::PipelineBindPoint::eGraphics,pipeline_layout,0,
    descriptor_set[ i ], ds_offset
    );
    ίϚϯυΛه࿥͢Δ
    ύΠϓϥΠϯͱ
    σεΫϦϓληοτΛ
    CJOE

    View Slide

  95. command_buffer[i].pushConstants(
    pipeline_layout,vk::ShaderStageFlagBits::eVertex,
    0,sizeof(glm::mat4),
    &scene_.get_matrices()[offset.matrix]
    );
    command_buffer[i].pushConstants(
    pipeline_layout,vk::ShaderStageFlagBits::eVertex,
    sizeof(glm::mat4),sizeof(glm::mat4),
    &scene_.get_cameras()[0]
    );
    std::vector vb_offsets{
    offset.vertex_begin*sizeof(vertex_t)
    };
    command_buffer[i].bindVertexBuffers(0,vb,vb_offsets);
    command_buffer[i].draw(offset.vertex_count,1,0,0);
    ίϚϯυΛه࿥͢Δ
    ࠲ඪม׵༻ͷߦྻΛॻ͍ͯ
    ௖఺όοϑΝΛCJOEͯ͠
    %SBXίʔϧ

    View Slide

  96. command_buffer[i].nextSubpass(vk::SubpassContents::eInline);
    command_buffer[i].bindPipeline(
    vk::PipelineBindPoint::eGraphics,graphics_pipeline[1]
    );
    command_buffer[i].draw(6,1,0,0);
    command_buffer[i].endRenderPass();
    command_buffer[i].end();
    ίϚϯυΛه࿥͢Δ
    vk::CommandBuffer::nextSubpassͰ
    ࣍ͷαϒύεʹҠΔ
    ύΠϓϥΠϯΛ੾Γସ͑ͯ2ͭΊͷαϒύεΛDraw
    ͦͷޙϨϯμʔύεΛऴྃͯ͠
    ίϚϯυͷه࿥Λऴྃ

    View Slide

  97. auto &fence=fences[current_frame];
    device.waitForFences(1,&fence,VK_TRUE,UINT64_MAX);
    device.resetFences(1,&fence);
    auto image_index=device.acquireNextImageKHR(
    swapchain,UINT64_MAX,
    image_acquired_semaphores[current_frame],
    vk::Fence()
    );
    auto &image=swapchain_images[image_index.value];
    vk::PipelineStageFlags const pipe_stage_flags=
    vk::PipelineStageFlagBits::eColorAttachmentOutput;
    const auto submit_info=vk::SubmitInfo()
    .setPWaitDstStageMask(&pipe_stage_flags)
    .setWaitSemaphoreCount(1)
    .setPWaitSemaphores(&image_acquired_semaphores[current_frame])
    .setCommandBufferCount(1)
    .setPCommandBuffers(&command_buffer[image_index.value])
    .setSignalSemaphoreCount(1)
    .setPSignalSemaphores(
    &draw_complete_semaphores[current_frame]
    );
    graphics_queue.submit(1,&submit_info,fences[current_frame]);
    ΩϡʔʹίϚϯυΛྲྀ͢
    εϫοϓνΣΠϯ͔Β
    දࣔதͰ΋ඳըதͰ΋ͳ͍ΠϝʔδΛ΋Β͏

    View Slide

  98. vk::Fence()
    );
    auto &image=swapchain_images[image_index.value];
    vk::PipelineStageFlags const pipe_stage_flags=
    vk::PipelineStageFlagBits::eColorAttachmentOutput;
    const auto submit_info=vk::SubmitInfo()
    .setPWaitDstStageMask(&pipe_stage_flags)
    .setWaitSemaphoreCount(1)
    .setPWaitSemaphores(&image_acquired_semaphores[current_frame])
    .setCommandBufferCount(1)
    .setPCommandBuffers(&command_buffer[image_index.value])
    .setSignalSemaphoreCount(1)
    .setPSignalSemaphores(
    &draw_complete_semaphores[current_frame]
    );
    graphics_queue.submit(1,&submit_info,fences[current_frame]);
    auto const presentInfo=vk::PresentInfoKHR()
    .setWaitSemaphoreCount(1)
    .setPWaitSemaphores(&draw_complete_semaphores[current_frame])
    .setSwapchainCount(1)
    .setPSwapchains(&swapchain)
    .setPImageIndices(&image_index.value);
    present_queue.presentKHR(&presentInfo);
    ΩϡʔʹίϚϯυΛྲྀ͢
    ίϚϯυόοϑΝΛΩϡʔʹsubmit͢Δ
    submit͸ඳըͷ׬ྃΛ଴ͨͣʹฦΔ͕
    fenceΛ౉͓͚ͯ͠͹
    ඳը׬ྃ࣌ʹγάφϧΛड͚औΔfenceʹͳΔ

    View Slide

  99. vk::Fence()
    );
    auto &image=swapchain_images[image_index.value];
    vk::PipelineStageFlags const pipe_stage_flags=
    vk::PipelineStageFlagBits::eColorAttachmentOutput;
    const auto submit_info=vk::SubmitInfo()
    .setPWaitDstStageMask(&pipe_stage_flags)
    .setWaitSemaphoreCount(1)
    .setPWaitSemaphores(&image_acquired_semaphores[current_frame])
    .setCommandBufferCount(1)
    .setPCommandBuffers(&command_buffer[image_index.value])
    .setSignalSemaphoreCount(1)
    .setPSignalSemaphores(
    &draw_complete_semaphores[current_frame]
    );
    graphics_queue.submit(1,&submit_info,fences[current_frame]);
    auto const presentInfo=vk::PresentInfoKHR()
    .setWaitSemaphoreCount(1)
    .setPWaitSemaphores(&draw_complete_semaphores[current_frame])
    .setSwapchainCount(1)
    .setPSwapchains(&swapchain)
    .setPImageIndices(&image_index.value);
    present_queue.presentKHR(&presentInfo);
    ΩϡʔʹίϚϯυΛྲྀ͢
    ηϚϑΥͰඳը׬ྃΛ଴ͬͯ
    ΠϝʔδΛදࣔՄೳʹ͢Δ

    View Slide

  100. छྨͷಉظ
    όϦΞ
    (16ଆͰಉҰϨϯμʔύε಺ͷαϒύεಉ͕࢜
    ॲཧͷ׬ྃΛ଴ͭͨΊͷಉظ
    ϑΣϯε
    (16ଆͰ࣮ߦ͞ΕΔॲཧͷ׬ྃΛ
    $16ଆͰ଴ͭͨΊͷಉظ
    ηϚϑΥ
    ҟͳΔΩϡʔͰ࣮ߦ͞ΕΔ(16ଆͷॲཧಉ࢜Ͱ
    ॲཧͷ׬ྃΛ଴ͭͨΊͷಉظ

    View Slide

  101. ࣮ߦ
    https://github.com/Fadis
    ιʔείʔυܝࡌ༧ఆ஍ ·্͕ͩͬͯͳ͍Α

    View Slide

  102. ·ͱΊ
    ݱ୅ͷ(16͕΍͍ͬͯΔ͜ͱΛ
    ͦͷ··ίϯτϩʔϧͰ͖ΔάϥϑΟοΫ"1*
    ϝϞϦΛͲ͏࢖͏͔
    ϨϯμϦϯάΛͲΜͳखॱͰߦ͏͔
    ԿΛ͍ͭ·ͰΩϟογϡ͢Δ͔
    શͯͷίϯτϩʔϧ͸ϓϩάϥϚͷखʹ

    View Slide