さすがstackoverflow.
How can I try out SIMD instructions in Chrome?
ChromeでSIMDを利用するには,ショートカットなどのChrome.exeに--js-flags="--harmony-simd"(ハイフン ハイフン js ハイフン flags = " ハイフン ハイフン harmony ハイフン simd")を指定すれば良いとのこと.
試してみたら,確かにSIMDというオブジェクトが増えていました.
2016年12月13日火曜日
2016年9月1日木曜日
Windows 10で起動したApache HTTPdサーバとPHPを連携させる
PHPのダウンロード
PHPのサイトからPHPをダウンロードします.トップのDownloadをクリックします.
Windows downloadsをクリックします.

Apache HTTPdサーバが32bit版ならx86を,64bit版ならx64のスレッドセーフまたは非スレッドセーフなものを選び,Zipをダウンロードします.ここでは,PHP 7.0.10のx64スレッドセーフ版をダウンロードしています.

ダウンロードしたZipの中身は,環境変数USERPROFILEで取得できるフォルダにphpという名前で解凍したものとします.
php.iniの用意
解凍したphpフォルダに,php.ini-developmentというファイルがあるので,php.iniにファイル名を変更しておきます.Apache HTTPdの設定ファイル編集
Apache HTTPdとPHPを連携させるために,httpd/conf/httpd.confを編集します.
まず,次のようにPHPを読み込むようにLoadModuleを追加します.
LoadModule php7_module "${USERPROFILE}/php/php7apache2_4.dll"次に,PHPファイルがphpとして処理されるように設定します.
<IfModule php7_module>
PHPIniDir "${USERPROFILE}/php"
<FilesMatch "\.php">
SetHandler application/x-httpd-php
</FilesMatch>
</IfModule>最後に,URLとしてフォルダが指定された場合に表示するファイルとして,phpのファイルも使えるようにします.
DirectoryIndex index.html index.php動作確認
httpd/htdocsフォルダにあるindex.htmlを消して,次の内容のindex.phpを用意します.
<?php phpinfo();?>これで,localhostにアクセスした際に,PHPの設定が確認できれば成功です.
上手くいかない場合,F5を押すなどして再読込をしてみると,キャッシュが消えて上手くいく場合があります.
2016年8月31日水曜日
Windows 10でApache HTTPdサーバーを実行する
事前条件
Visual Studio 2015 のVisual C++ 再頒布可能パッケージをインストールしておく必要があります.再頒布可能パッケージは,Microsoftのダウンロードセンターからダウンロードできます.
Apache HTTPdサーバのダウンロード
Apache HTTPdサーバのページの左メニューから,Download!のFrom A Mirrorを選び,Files for Microsoft Windowsを選びます.
Apache HTTPdサーバのWindows向けバイナリを配布しているサイトがいくつかありますが,ここではApache Loungeを選択します.
Apache HTTPdサーバの本体をダウンロードします.この記事を書いた時点での最新版は,2.4.23です.ここでは,64bit版をダウンロードしていますが,32bit版でも手順は変わりません.
ただし,PHPなどと連携する場合,HTTPdサーバが32bit版ならPHPも32bit版,といったように同じbit数のものを選ぶ必要があります.
ダウンロードしたら,解凍し,中にあるApache24というフォルダを取り出します.ここでは,ユーザーのホームフォルダ(環境変数USERPROFILEで指定されているフォルダ)にhttpdという名前で取り出したこととします.
httpdフォルダの中にconfというフォルダがあり,その中にhttpd.confという設定ファイルがあります.Apache HTTPdサーバを起動するには,最低限,以下の項目を設定する必要があります.
- ServerRoot
- "${USERPROFILE}/httpd"に書き換えます.
- DocumentRoot
- "${USERPROFILE}/httpd/htdocs"に書き換えます.
- 直下のDirectoryの部分も同様に書き換えます.
- ServerName
- 先頭の#を消してコメントを解除します.
- localhost:80に書き換えます.
これで準備ができたので,Apache HTTPdサーバを起動します.httpdフォルダの中に,binというフォルダがあり,その中にhttpd.exeがあるのでクリックして起動します.
http://localhostにアクセスして,It Works!と表示されれば起動しています.
先にSkypeが起動していると,Apache HTTPdサーバが起動しない場合があります.Skypeを起動している場合,一度Skypeを終了して,Apache HTTPdサーバを起動した後にSkypeを再起動するようにしてみてください.
あとは,httpdフォルダのhtdocsフォルダを基準として,相対パスを指定すれば,そのファイルをHTTPdサーバ経由で取得することができます.例えば,http://localhost/hello.htmlというパスをウェブブラウザに指定すると,htdocsフォルダのhello.htmlを取得することになります.
2016年7月6日水曜日
Vulkan - インスタンスの生成と破棄
ようやくVulkanインスタンスを生成します.
この構造体を初期化するために,構造体VkApplicationInfoを初期化する必要があります.
構造体VkApplicationInfoは,次のような構造になっています.
sTypeには,VK_STRUCTURE_TYPE_APPLICATION_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
apiVersionには,VK_API_VERSION_1_0を設定します.今のところ,他のバージョンを設定するとインスタンスが生成できない場合があります.
pApplicatoinName,applicationVersion,pEngineName,engineVersionは適当でも大丈夫そうですが,今後どうなるかは分かりません.
sTypeには,VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
flagsは今後のために予約されており,現時点では0を指定します.
pApplicationInfoには,前もって初期化しておいたVkApplicationInfoの変数へのポインタを設定します.
enabledLayerCountには有効にしたいレイヤーの数を,ppEnabledLayerNamesには有効にしたいレイヤー名へのポインタの配列を設定します.
enabledExtensionCount,ppEnabledExtensionNamesもレイヤーと同様に,有効にしたい拡張機能の数と名前へのポインタの配列を設定します.
pCreateInfoには,初期化しておいたVkInstanceCreateInfoの変数へのポインタを渡します.
pAllocatorは,nullptrを指定します.適切な設定をすると,メモリ管理を制御できるのですが,今回は触れません.
pInstanceには,実際に生成されたVulkanインスタンスへのハンドルが設定されるので,VkInstanceの変数へのポインタを渡します.
サンプルコードは,ryutorion/LearningVulkan (GitHubリポジトリ)の003_CreateInstanceにもあります.
VkApplicationInfoの初期化
Vulkanインスタンスを生成するために,構造体VkInstanceCreateInfoが必要です.この構造体を初期化するために,構造体VkApplicationInfoを初期化する必要があります.
構造体VkApplicationInfoは,次のような構造になっています.
struct VkApplicationInfo {
VkStructureType sType;
const void* pNext;
const char* pApplicationName;
uint32_t applicationVersion;
const char* pEngineName;
uint32_t engineVersion;
uint32_t apiVersion;
};sTypeには,VK_STRUCTURE_TYPE_APPLICATION_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
apiVersionには,VK_API_VERSION_1_0を設定します.今のところ,他のバージョンを設定するとインスタンスが生成できない場合があります.
pApplicatoinName,applicationVersion,pEngineName,engineVersionは適当でも大丈夫そうですが,今後どうなるかは分かりません.
VkInstanceCreateInfoの初期化
VkApplicationInfoを初期化したら,VkInstanceCreateInfoを初期化します.VkInstanceCreateInfoは次のような構造になっています.struct VkInstanceCreateInfo {
VkStructureType sType;
const void* pNext;
VkInstanceCreateFlags flags;
const VkApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
};sTypeには,VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
flagsは今後のために予約されており,現時点では0を指定します.
pApplicationInfoには,前もって初期化しておいたVkApplicationInfoの変数へのポインタを設定します.
enabledLayerCountには有効にしたいレイヤーの数を,ppEnabledLayerNamesには有効にしたいレイヤー名へのポインタの配列を設定します.
enabledExtensionCount,ppEnabledExtensionNamesもレイヤーと同様に,有効にしたい拡張機能の数と名前へのポインタの配列を設定します.
Vulkanインスタンスの生成
VkInstanceCreateInfoが初期化できたら,次のようなvkCreateInstance()を呼び出してVulkanインスタンスを生成します.VkResult vkCreateInstance(
const VkInstanceCreateInfo * pCreateInfo,
const VkAllocationCallbacks * pAllocator,
VkInstance * pInstance
);pCreateInfoには,初期化しておいたVkInstanceCreateInfoの変数へのポインタを渡します.
pAllocatorは,nullptrを指定します.適切な設定をすると,メモリ管理を制御できるのですが,今回は触れません.
pInstanceには,実際に生成されたVulkanインスタンスへのハンドルが設定されるので,VkInstanceの変数へのポインタを渡します.
Vulkanインスタンスの破棄
最後に,次のようなvkDestroyInstance()を呼び出してインスタンスを破棄して終了です.void vkDestroyInstance(
VkInstance * pInstance
const VkAllocationCallbacks * pAllocator
);実例
以下は,実際にVulkanインスタンスを生成して破棄するだけのコードです.本来は,それぞれのレイヤーがあるかどうか,拡張機能は利用できるかどうか,などを確認すべきですが,ここではそのあたりは省略しています.#include <iostream>
#include <vector>
#include <vulkan/vulkan.h>
#pragma comment(lib, "vulkan-1")
using namespace std;
int main()
{
// アプリケーション情報を初期化
VkApplicationInfo applicationInfo {};
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pNext = nullptr;
applicationInfo.pApplicationName = "";
applicationInfo.applicationVersion = 0;
applicationInfo.pEngineName = "";
applicationInfo.engineVersion = 0;
// VK_VERSION_1_0と間違えないこと
applicationInfo.apiVersion = VK_API_VERSION_1_0;
// APIの実引数をダンプしてくれるレイヤーを有効化しておく
vector<const char *> layerNames {
"VK_LAYER_LUNARG_api_dump"
};
// 今後必要になる拡張機能を有効にしておく
vector<const char *> extensionNames {
"VK_KHR_surface",
"VK_KHR_win32_surface"
};
// インスタンス生成情報を初期化
VkInstanceCreateInfo instanceCreateInfo {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pNext = nullptr;
instanceCreateInfo.flags = 0;
instanceCreateInfo.pApplicationInfo = &applicationInfo;
instanceCreateInfo.enabledLayerCount = layerNames.size();
instanceCreateInfo.ppEnabledLayerNames = layerNames.data();
instanceCreateInfo.enabledExtensionCount = extensionNames.size();
instanceCreateInfo.ppEnabledExtensionNames = extensionNames.data();
// Vulkanインスタンスを生成
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
if(result != VK_SUCCESS)
{
cerr << "Vulkanインスタンスの生成に失敗" << endl;
return -1;
}
cout << "Vulkanインスタンスの生成に成功" << endl;
vkDestroyInstance(instance, nullptr);
}サンプルコードは,ryutorion/LearningVulkan (GitHubリポジトリ)の003_CreateInstanceにもあります.
Vulkan - インスタンス拡張機能の列挙
拡張機能とは
レイヤーの列挙,でも書いたように,レイヤーはVulkan APIによって発行されるコマンドに割り込みをかけるものです.一方,拡張機能はVulkanのコマンドなどを追加します.
インスタンス拡張機能の列挙
拡張機能を列挙するための手順は,レイヤーを列挙する際の手順に似ています.インスタンス拡張機能の場合,次のようなvkEnumerateInstanceExtensionProperties()を呼び出します.VkResult vkEnumerateInstanceExtensionProperties(
const char * pLayerName,
uint32_t * pPropertyCount,
VkExtensionProperties * pProperties
);仮引数の名前を見ると分かるように,インスタンス拡張機能はレイヤーに紐付いています.ただし,pLayerNameにnullptrを指定することも可能で,その場合はデフォルトで利用可能なインスタンス拡張が列挙されます.
インスタンス拡張機能の情報は,次のような構造体に保存されます.
struct VkExtensionProperties {
char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
uint32_t specVersion;
};以下の例では,利用可能なレイヤー名を全て取得し,更にnullptrを追加した上で,インスタンス拡張を列挙して,その情報をダンプしています.
#include <iostream>
#include <vector>
#include <vulkan/vulkan.h>
#pragma comment(lib, "vulkan-1")
using namespace std;
class version
{
public:
version(uint32_t value) : mValue(value) {}
uint32_t value() const { return mValue; }
uint32_t major() const { return VK_VERSION_MAJOR(mValue); }
uint32_t minor() const { return VK_VERSION_MINOR(mValue); }
uint32_t patch() const { return VK_VERSION_PATCH(mValue); }
private:
uint32_t mValue;
};
std::ostream & operator<<(std::ostream & out, const version & v)
{
out << v.major() << "." << v.minor() << "." << v.patch();
return out;
}
int main()
{
VkResult result = VK_SUCCESS;
vector<VkLayerProperties> layers {};
do {
uint32_t count = 0;
result = vkEnumerateInstanceLayerProperties(&count, nullptr);
if(result != VK_SUCCESS)
{
break;
}
layers.resize(count);
result = vkEnumerateInstanceLayerProperties(&count, layers.data());
} while(result == VK_INCOMPLETE);
// レイヤー名の配列を生成
vector<const char *> layerNames(layers.size() + 1);
for(auto i = 0; i < layers.size(); ++i)
{
layerNames[i] = layers[i].layerName;
}
layerNames[layers.size()] = nullptr;
for(auto layerName : layerNames)
{
cout << (layerName ? layerName : "No Layer Name") << endl;
// レイヤーに対応する拡張の取得
vector<VkExtensionProperties> extensions;
do {
uint32_t count = 0;
result = vkEnumerateInstanceExtensionProperties(layerName, &count, nullptr);
if(result != VK_SUCCESS)
{
break;
}
extensions.resize(count);
result = vkEnumerateInstanceExtensionProperties(layerName, &count, extensions.data());
} while(result == VK_INCOMPLETE);
for(auto & extension : extensions)
{
cout << "\tExtension Name : " << extension.extensionName << endl;
cout << "\tSpecification Version : " << version(extension.specVersion) << endl;
cout << endl;
}
}
}GitHubのリポジトリryutorion/LearningVulkanの002_EnumerateInstanceExtensionsに実際のコードがあります.
2016年7月5日火曜日
Vulkan - レイヤーの列挙
最近ブログ書いてなかったので,Vulkanについて調べたり試したことを書いていこうかと思います.
まず,pPropertyCountに変数へのポインタ,pPropertiesにnullptrを渡すことでレイヤーの数を取得します.
次に,必要なバッファを用意して各レイヤーの情報を取得します.ここでは,vectorクラスを利用しています.
実際に各レイヤーの情報を取得する際に,レイヤーの数を取得してから情報を取得するまでの間に,レイヤーが追加される場合があります.そんな珍しい状況が発生した場合,vkEnumerateInstanceLayerProperties()はVK_INCOMPLETEを返します.VK_INCOMPLETEが返された場合,レイヤー数の取得からやり直します.
取得されたレイヤーの情報は,次のような構造体に格納されます.
インスタンスを生成する際には上記の手順で取得したレイヤーを指定すれば良いのですが,まだ問題が起きるレイヤーがあります.しばらくは,レイヤーの使用に問題が無いか確認してから,本番環境で有効化するか検討した方が良いでしょう.
サンプルコードは,ryutorion/LearningVulkan (GitHubリポジトリ)の001_EnumerateInstanceLayerにもあります.
環境
| OS | Windows 10 Pro |
| GPU | NVIDIA GeForce GTX 860M (ドライバー 368.22) |
| Vulkan SDKバージョン | 1.0.17.0 |
レイヤーとは
Vulkanのインスタンス,またはインスタンスを介して生成されたオブジェクトに対して発行されるVulkanのコマンドに対して,割り込みをかけるための機能です.
例えば,VK_LAYER_LUNARG_api_dumpというレイヤーは,VulkanのAPIを実行した際に,実引数をダンプしてくれます.
レイヤーは,Vulkanのインスタンスを生成する際に指定することで有効になります.
レイヤーの列挙
利用可能なレイヤーの一覧を取得するには,次のvkEnumerateInstanceLayerProperties()を利用します.VkResult vkEnumerateInstanceLayerProperties(
uint32_t * pPropertyCount,
VkLayerProperties * pProperties
);まず,pPropertyCountに変数へのポインタ,pPropertiesにnullptrを渡すことでレイヤーの数を取得します.
uint32_t count;
vkEnumerateInstanceLayerProperties(&count, nullptr);次に,必要なバッファを用意して各レイヤーの情報を取得します.ここでは,vectorクラスを利用しています.
vector<VkLayerProperties> layers {};
VkResult result = vkEnumerateInstanceLayerProperties(&count, layers.data());実際に各レイヤーの情報を取得する際に,レイヤーの数を取得してから情報を取得するまでの間に,レイヤーが追加される場合があります.そんな珍しい状況が発生した場合,vkEnumerateInstanceLayerProperties()はVK_INCOMPLETEを返します.VK_INCOMPLETEが返された場合,レイヤー数の取得からやり直します.
取得されたレイヤーの情報は,次のような構造体に格納されます.
struct VkLayerProperties {
char layerName[VK_MAX_EXTENSION_NAME_SIZE];
uint32_t specVersion;
uint32_t implementationVersion;
char description[VK_MAX_DESCRIPTION_SIZE];
};サンプルコード
以下のコードは,vkEnumerateInstanceLayerProperties()を使って,全てのレイヤー情報をダンプするものです.Vulkanのバージョン情報を分かりやすい形で表示するために,versionクラスを導入しています.#include <iostream>
#include <vector>
#include <vulkan/vulkan.h>
#pragma comment(lib, "vulkan-1")
using namespace std;
class version
{
public:
version(uint32_t value) : mValue(value) {}
//! 値を返す
uint32_t value() const { return mValue; }
//! メジャーバージョンを返す
uint32_t major() const { return VK_VERSION_MAJOR(mValue); }
//! マイナーバージョンを返す
uint32_t minor() const { return VK_VERSION_MINOR(mValue); }
//! パッチバージョンを返す
uint32_t patch() const { return VK_VERSION_PATCH(mValue); }
private:
uint32_t mValue;
};
std::ostream & operator<<(std::ostream & out, const version & v)
{
out << v.major() << "." << v.minor() << "." << v.patch();
return out;
}
int main()
{
VkResult result = VK_SUCCESS;
vector layers {};
do {
// レイヤー数を取得
uint32_t count = 0;
result = vkEnumerateInstanceLayerProperties(&count, nullptr);
if(result != VK_SUCCESS)
{
break;
}
// 各レイヤーのプロパティを取得
layers.resize(count);
result = vkEnumerateInstanceLayerProperties(&count, layers.data());
// 全てのレイヤーを取得していない場合,やり直す
} while(result == VK_INCOMPLETE);
// 各レイヤーのプロパティを出力する
for(auto layer : layers)
{
cout << "Layer Name : " << layer.layerName << endl;
cout << "Specification Version : " << version(layer.specVersion) << endl;
cout << "Implementation Version : " << version(layer.implementationVersion) << endl;
cout << "Description : " << layer.description << endl;
cout << endl;
}
} インスタンスを生成する際には上記の手順で取得したレイヤーを指定すれば良いのですが,まだ問題が起きるレイヤーがあります.しばらくは,レイヤーの使用に問題が無いか確認してから,本番環境で有効化するか検討した方が良いでしょう.
サンプルコードは,ryutorion/LearningVulkan (GitHubリポジトリ)の001_EnumerateInstanceLayerにもあります.
2016年3月9日水曜日
Code alignment Visual Studio拡張
ふと思い立って検索したところ,Code alignmentというVisual Studioの拡張機能を見つけました.
名前の通り,コードの整列をしてくれる拡張機能です.なお,Notepad++にも対応しているようです.
例えば,こんなコードがあったとします.
Ctrl+Shift+;でダイアログを表示し,そろえるための文字を指定します.
例えば,"="を指定すると,次のようになります.
ブログの幅の関係で汚く見えるかもしれませんが,Visual Studio上で見る分にはスッキリして見えます.
また,よく使うパターンについてはショートカットが用意されています.
Tools(ツール) > Options(オプション) > Environment(環境) > Keyboard(キーボード)でEdit.Alignあたりまでを検索ボックスに入力すると,ショートカットが確認でき,ショートカットキーを割り当てることができます.
例えば,Edit.AlignByEqual(=で整列),Edit.AlignByEqualEqual(==で整列)などがあるようです.
名前の通り,コードの整列をしてくれる拡張機能です.なお,Notepad++にも対応しているようです.
例えば,こんなコードがあったとします.
DXGI_SWAP_CHAIN_DESC SwapChainDesc{};
SwapChainDesc.BufferDesc.Width = Width;
SwapChainDesc.BufferDesc.Height = Height;
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.BufferCount = 1;
SwapChainDesc.OutputWindow = hWnd;
SwapChainDesc.Windowed = TRUE;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
SwapChainDesc.Flags = 0;Ctrl+Shift+;でダイアログを表示し,そろえるための文字を指定します.
例えば,"="を指定すると,次のようになります.
SwapChainDesc.BufferDesc.Width = Width;
SwapChainDesc.BufferDesc.Height = Height;
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.BufferCount = 1;
SwapChainDesc.OutputWindow = hWnd;
SwapChainDesc.Windowed = TRUE;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
SwapChainDesc.Flags = 0;ブログの幅の関係で汚く見えるかもしれませんが,Visual Studio上で見る分にはスッキリして見えます.
また,よく使うパターンについてはショートカットが用意されています.
Tools(ツール) > Options(オプション) > Environment(環境) > Keyboard(キーボード)でEdit.Alignあたりまでを検索ボックスに入力すると,ショートカットが確認でき,ショートカットキーを割り当てることができます.
例えば,Edit.AlignByEqual(=で整列),Edit.AlignByEqualEqual(==で整列)などがあるようです.
登録:
投稿 (Atom)



