void Image::createTexture(VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkFlags requiredProps, uint32_t width, uint32_t height, uint32_t depth, VkImageLayout iLayout, uint32_t layers) { imageInfo = ImageCreateInfo(format, usage, width, height, depth, layers); imageInfo.tiling = tiling; imageInfo.initialLayout = iLayout == VK_IMAGE_LAYOUT_PREINITIALIZED ? VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED; OBJ_CHECK(vkCreateImage(vk, &imageInfo, NULL, &image)); VkMemoryRequirements requirements; vkGetImageMemoryRequirements(vk, image, &requirements); allocInfo = MemoryAllocateInfo(requirements, requiredProps); OBJ_CHECK(vkAllocateMemory(vk, &allocInfo, NULL, &mem)); OBJ_CHECK(vkBindImageMemory(vk, image, mem, 0)); if (iLayout != VK_IMAGE_LAYOUT_PREINITIALIZED && iLayout != VK_IMAGE_LAYOUT_UNDEFINED) { setLayout(VK_IMAGE_ASPECT_COLOR_BIT, imageInfo.initialLayout, iLayout); } if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) != 0) { ImageViewCreateInfo viewInfo(image, format, VK_IMAGE_ASPECT_COLOR_BIT); if (layers == 1) { viewInfo.viewType = depth > 1 ? VK_IMAGE_VIEW_TYPE_3D : height > 1 ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D; } else { viewInfo.subresourceRange.layerCount = layers; viewInfo.viewType = height > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY; } OBJ_CHECK(vkCreateImageView(vk, &viewInfo, NULL, &view)); } }
void Image::createDepth(uint32_t width, uint32_t height) { imageInfo = ImageCreateInfo(VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, width, height); OBJ_CHECK(vkCreateImage(vk, &imageInfo, NULL, &image)); VkMemoryRequirements requirements; vkGetImageMemoryRequirements(vk, image, &requirements); allocInfo = MemoryAllocateInfo(requirements); OBJ_CHECK(vkAllocateMemory(vk, &allocInfo, NULL, &mem)); OBJ_CHECK(vkBindImageMemory(vk, image, mem, 0)); setLayout(VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); ImageViewCreateInfo viewInfo(image, imageInfo.format, VK_IMAGE_ASPECT_DEPTH_BIT); OBJ_CHECK(vkCreateImageView(vk, &viewInfo, NULL, &view)); }
bool ShaderProgram::compile(const char *name) { EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); glslang::TProgram program; const char *stageNames[StageCount] = {"Vertex", "TessControl", "TessEvaluation", "Geometry", "Fragment", "Compute"}; const char *extensions[StageCount] = { "vert", "tesc", "tese", "geom", "frag", "comp" }; glslang::TShader tShaders[EShLangCount] = { glslang::TShader(EShLangVertex), glslang::TShader(EShLangTessControl), glslang::TShader(EShLangTessEvaluation), glslang::TShader(EShLangGeometry), glslang::TShader(EShLangFragment), glslang::TShader(EShLangCompute) }; //#define glslangValidator "C:\\VulkanSDK\\1.0.21.1\\Bin\\glslangValidator.exe" #ifdef glslangValidator char szCommand[1024]; sprintf(szCommand, glslangValidator " -V"); #endif const char *psz = NULL; for (int i = 0; i < EShLangCount; i++) { if (stages[i].glsl.empty()) continue; #ifdef glslangValidator VK::Path pGLSL = VK::Path::Shader().add("temp.%s", extensions[i]); strcat(szCommand, " "); strcat(szCommand, pGLSL.basename().c_str()); std::ofstream os(pGLSL, std::ios::binary); os << stages[i].glsl; os.close(); #endif psz = stages[i].glsl.c_str(); tShaders[i].setStrings(&psz, 1); if (!stages[i].entry.empty()) tShaders[i].setEntryPoint(stages[i].entry.c_str()); VKLogDebug("%s stage for program: %s\n%s", stageNames[i], name, stages[i].glsl.c_str()); if (!tShaders[i].parse(&DefaultTBuiltInResource, 110, false, messages)) { psz = tShaders[i].getInfoLog(); if (psz && *psz) VKLogError("%s", psz); return false; } psz = tShaders[i].getInfoLog(); if (psz && *psz) VKLogInfo("%s stage parsing info for program: %s\n%s", stageNames[i], name, psz); psz = tShaders[i].getInfoDebugLog(); if (psz && *psz) VKLogDebug("%s stage debug info for program: %s\n%s", stageNames[i], name, psz); program.addShader(&tShaders[i]); } if (!program.link(messages)) { psz = program.getInfoLog(); if (psz && *psz) VKLogError("Link failed for program: %s\n%s", name, psz); return false; } #ifdef glslangValidator LaunchAndWait(szCommand, VK::Path::Shader(), 0, 0, SW_HIDE); #endif for (int i = 0; i < EShLangCount; i++) { stages[i].spirv.clear(); if (stages[i].module) { vkDestroyShaderModule(vk, stages[i].module, NULL); stages[i].module = NULL; } glslang::TIntermediate *intermediate = program.getIntermediate((EShLanguage)i); if (intermediate) { glslang::GlslangToSpv(*intermediate, stages[i].spirv); #ifdef glslangValidator VK::Path p = VK::Path::Shader().add("%s.spv", extensions[i]); std::string str = p.read(); std::vector<uint32_t> spirv; spirv.resize(str.size() / 4); memcpy(&spirv[0], str.c_str(), str.size()); if (spirv.size() != stages[i].spirv.size() || memcmp(&spirv[0], &stages[i].spirv[0], spirv.size() * 4) != 0) VKLogWarning("glslangValidator mismatch!"); #endif std::ostringstream ostr; spv::Disassemble(ostr, stages[i].spirv); VKLogDebug("%s stage dissassembly for program: %s\n%s", stageNames[i], name, ostr.str().c_str()); ShaderModuleCreateInfo shader(stages[i].spirv); OBJ_CHECK(vkCreateShaderModule(vk, &shader, nullptr, &stages[i].module)); } } return true; }
/* this gets called each time the settings dialog is opened: */ static void display_settings(void) { char spare[255]; // read current settings and display them /* "Browser" tab: */ set_text( SETTINGS_EDIT_HOMEPAGE, nsoption_charp(homepage_url), INPUT_HOMEPAGE_URL_MAX_LEN ); if( nsoption_bool(block_ads) ) { OBJ_CHECK( SETTINGS_CB_HIDE_ADVERTISEMENT ); } else { OBJ_UNCHECK( SETTINGS_CB_HIDE_ADVERTISEMENT ); } if( nsoption_bool(target_blank) ) { OBJ_UNCHECK( SETTINGS_CB_DISABLE_POPUP_WINDOWS ); } else { OBJ_CHECK( SETTINGS_CB_DISABLE_POPUP_WINDOWS ); } if( nsoption_bool(send_referer) ) { OBJ_CHECK( SETTINGS_CB_SEND_HTTP_REFERRER ); } else { OBJ_UNCHECK( SETTINGS_CB_SEND_HTTP_REFERRER ); } if( nsoption_bool(do_not_track) ) { OBJ_CHECK( SETTINGS_CB_SEND_DO_NOT_TRACK ); } else { OBJ_UNCHECK( SETTINGS_CB_SEND_DO_NOT_TRACK ); } set_text( SETTINGS_BT_SEL_LOCALE, nsoption_charp(accept_language) ? nsoption_charp(accept_language) : (char*)"en", INPUT_LOCALE_MAX_LEN ); tmp_option_expire_url = nsoption_int(expire_url); snprintf( spare, 255, "%02d", nsoption_int(expire_url) ); set_text( SETTINGS_EDIT_HISTORY_AGE, spare, 2 ); /* "Cache" tab: */ tmp_option_memory_cache_size = nsoption_int(memory_cache_size) / 1000000; snprintf( spare, 255, "%03.1f", tmp_option_memory_cache_size ); set_text( SETTINGS_STR_MAX_MEM_CACHE, spare, 5 ); /* "Paths" tab: */ set_text( SETTINGS_EDIT_DOWNLOAD_PATH, nsoption_charp(downloads_path), LABEL_PATH_MAX_LEN ); set_text( SETTINGS_EDIT_HOTLIST_FILE, nsoption_charp(hotlist_file), LABEL_PATH_MAX_LEN ); set_text( SETTINGS_EDIT_CA_BUNDLE, nsoption_charp(ca_bundle), LABEL_PATH_MAX_LEN ); set_text( SETTINGS_EDIT_CA_CERTS_PATH, nsoption_charp(ca_path), LABEL_PATH_MAX_LEN ); set_text( SETTINGS_EDIT_EDITOR, nsoption_charp(atari_editor), LABEL_PATH_MAX_LEN ); /* "Rendering" tab: */ set_text( SETTINGS_BT_SEL_FONT_RENDERER, nsoption_charp(atari_font_driver), LABEL_FONT_RENDERER_MAX_LEN ); SET_BIT(dlgtree[SETTINGS_CB_TRANSPARENCY].ob_state, OS_SELECTED, nsoption_int(atari_transparency) ? 1 : 0 ); SET_BIT(dlgtree[SETTINGS_CB_ENABLE_ANIMATION].ob_state, OS_SELECTED, nsoption_bool(animate_images) ? 1 : 0 ); SET_BIT(dlgtree[SETTINGS_CB_FG_IMAGES].ob_state, OS_SELECTED, nsoption_bool(foreground_images) ? 1 : 0 ); SET_BIT(dlgtree[SETTINGS_CB_BG_IMAGES].ob_state, OS_SELECTED, nsoption_bool(background_images) ? 1 : 0 ); // TODO: enable this option? /* SET_BIT(dlgtree[SETTINGS_CB_INCREMENTAL_REFLOW].ob_state, OS_SELECTED, nsoption_bool(incremental_reflow) ? 1 : 0 );*/ SET_BIT(dlgtree[SETTINGS_CB_ANTI_ALIASING].ob_state, OS_SELECTED, nsoption_int(atari_font_monochrom) ? 0 : 1 ); // TODO: activate this option? tmp_option_min_reflow_period = nsoption_int(min_reflow_period); snprintf( spare, 255, "%04d", tmp_option_min_reflow_period ); set_text( SETTINGS_EDIT_MIN_REFLOW_PERIOD, spare, INPUT_MIN_REFLOW_PERIOD_MAX_LEN ); tmp_option_minimum_gif_delay = (float)nsoption_int(minimum_gif_delay) / (float)100; snprintf( spare, 255, "%01.1f", tmp_option_minimum_gif_delay ); set_text( SETTINGS_EDIT_MIN_GIF_DELAY, spare, 3 ); /* "Network" tab: */ set_text( SETTINGS_EDIT_PROXY_HOST, nsoption_charp(http_proxy_host), INPUT_PROXY_HOST_MAX_LEN ); snprintf( spare, 255, "%5d", nsoption_int(http_proxy_port) ); set_text( SETTINGS_EDIT_PROXY_PORT, spare, INPUT_PROXY_PORT_MAX_LEN ); set_text( SETTINGS_EDIT_PROXY_USERNAME, nsoption_charp(http_proxy_auth_user), INPUT_PROXY_USERNAME_MAX_LEN ); set_text( SETTINGS_EDIT_PROXY_PASSWORD, nsoption_charp(http_proxy_auth_pass), INPUT_PROXY_PASSWORD_MAX_LEN ); SET_BIT(dlgtree[SETTINGS_CB_USE_PROXY].ob_state, OS_SELECTED, nsoption_bool(http_proxy) ? 1 : 0 ); SET_BIT(dlgtree[SETTINGS_CB_PROXY_AUTH].ob_state, OS_SELECTED, nsoption_int(http_proxy_auth) ? 1 : 0 ); tmp_option_max_cached_fetch_handles = nsoption_int(max_cached_fetch_handles); snprintf( spare, 255, "%2d", nsoption_int(max_cached_fetch_handles) ); set_text( SETTINGS_EDIT_MAX_CACHED_CONNECTIONS, spare , 2 ); tmp_option_max_fetchers = nsoption_int(max_fetchers); snprintf( spare, 255, "%2d", nsoption_int(max_fetchers) ); set_text( SETTINGS_EDIT_MAX_FETCHERS, spare , 2 ); tmp_option_max_fetchers_per_host = nsoption_int(max_fetchers_per_host); snprintf( spare, 255, "%2d", nsoption_int(max_fetchers_per_host) ); set_text( SETTINGS_EDIT_MAX_FETCHERS_PER_HOST, spare , 2 ); /* "Style" tab: */ tmp_option_font_min_size = nsoption_int(font_min_size); snprintf( spare, 255, "%3d", nsoption_int(font_min_size) ); set_text( SETTINGS_EDIT_MIN_FONT_SIZE, spare , 3 ); tmp_option_font_size = nsoption_int(font_size); snprintf( spare, 255, "%3d", nsoption_int(font_size) ); set_text( SETTINGS_EDIT_DEF_FONT_SIZE, spare , 3 ); toggle_objects(); }
void Image::loadTexture(const char *path) { PixelBuffer<uint8_t> pb; if(!pb.load(path)) throw "Failed to load texture"; VkFormatProperties &props = formatProperties[VK_FORMAT_R8G8B8A8_UNORM]; bool direct = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0; VkImageSubresource subres = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; VkSubresourceLayout sublayout; createTexture(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, direct ? VK_IMAGE_USAGE_SAMPLED_BIT : VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, pb.getWidth(), pb.getHeight()); vkGetImageSubresourceLayout(vk, image, &subres, &sublayout); uint8_t *data = NULL; OBJ_CHECK(vkMapMemory(vk, mem, 0, allocInfo.allocationSize, 0, (void **)&data)); uint32_t x = 0, y = 0; uint8_t temp[4] = {0, 0, 0, 255}; for (y = 0; y < pb.getHeight(); y++) { uint32_t *dest = (uint32_t *)data; uint8_t *src = pb(0, y); switch (pb.getChannels()) { case 4: memcpy(dest, src, pb.getWidth() * 4); break; case 3: for (x = 0; x < pb.getWidth(); x++) { temp[0] = *src++; // R temp[1] = *src++; // G temp[2] = *src++; // B *dest++ = *(uint32_t *)temp; } break; case 2: for (x = 0; x < pb.getWidth(); x++) { temp[0] = *src++; // R temp[1] = *src++; // G *dest++ = *(uint32_t *)temp; } break; case 1: for (x = 0; x < pb.getWidth(); x++) { temp[0] = *src++; // R *dest++ = *(uint32_t *)temp; } break; } data += sublayout.rowPitch; } vkUnmapMemory(vk, mem); if (direct) { setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } else { // Create a staging image visible to the host to load the texture into with linear tiling Image staging; Math::Swap(staging.image, image); Math::Swap(mem, staging.mem); Math::Swap(layout, staging.layout); Math::Swap(imageInfo, staging.imageInfo); Math::Swap(allocInfo, staging.allocInfo); staging.setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // Now create the actual device-local image and copy into it from the staging image createTexture(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pb.getWidth(), pb.getHeight()); setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); ImageCopy copy_region(pb.getWidth(), pb.getHeight()); vkCmdCopyImage(vk, staging.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); setLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); vk.flush(); // Wait for the copy command to complete before the staging texture goes out of scope! } ImageViewCreateInfo viewInfo(image, imageInfo.format, VK_IMAGE_ASPECT_COLOR_BIT); OBJ_CHECK(vkCreateImageView(vk, &viewInfo, NULL, &view)); }