//============================================================================== Error Material::getProgramPipeline( const RenderingKey& key, GlPipelineHandle& out) { ANKI_ASSERT(enumToType(key.m_pass) < m_passesCount); ANKI_ASSERT(key.m_lod < m_lodsCount); Error err = ErrorCode::NONE; U tessCount = 1; if(m_tessellation) { tessCount = 2; } else { ANKI_ASSERT(!key.m_tessellation); } U idx = enumToType(key.m_pass) * m_lodsCount * tessCount + key.m_lod * tessCount + key.m_tessellation; GlPipelineHandle& ppline = m_pplines[idx]; // Lazily create it if(ANKI_UNLIKELY(!ppline.isCreated())) { Array<GlShaderHandle, 5> progs; U progCount = 0; progs[progCount++] = getProgram(key, ShaderType::VERTEX)->getGlProgram(); if(key.m_tessellation) { progs[progCount++] = getProgram( key, ShaderType::TESSELLATION_CONTROL)->getGlProgram(); progs[progCount++] = getProgram( key, ShaderType::TESSELLATION_EVALUATION)->getGlProgram(); } progs[progCount++] = getProgram(key, ShaderType::FRAGMENT)->getGlProgram(); GlDevice& gl = m_resources->_getGlDevice(); GlCommandBufferHandle cmdBuff; ANKI_CHECK(cmdBuff.create(&gl)); ANKI_CHECK(ppline.create(cmdBuff, &progs[0], &progs[0] + progCount)); cmdBuff.flush(); } out = ppline; return err; }
//============================================================================== void Pps::initInternal(const ConfigSet& config) { m_enabled = config.get("pps.enabled"); if(!m_enabled) { return; } ANKI_ASSERT("Initializing PPS"); m_ssao.init(config); m_hdr.init(config); m_lf.init(config); m_sslr.init(config); // FBO GlCommandBufferHandle cmdBuff; cmdBuff.create(&getGlDevice()); m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 1, m_rt); m_fb.create(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}}); // SProg String pps(getAllocator()); pps.sprintf( "#define SSAO_ENABLED %u\n" "#define HDR_ENABLED %u\n" "#define SHARPEN_ENABLED %u\n" "#define GAMMA_CORRECTION_ENABLED %u\n" "#define FBO_WIDTH %u\n" "#define FBO_HEIGHT %u\n", m_ssao.getEnabled(), m_hdr.getEnabled(), static_cast<U>(config.get("pps.sharpen")), static_cast<U>(config.get("pps.gammaCorrection")), m_r->getWidth(), m_r->getHeight()); m_frag.loadToCache(&getResourceManager(), "shaders/Pps.frag.glsl", pps.toCString(), "r_"); m_ppline = m_r->createDrawQuadProgramPipeline(m_frag->getGlProgram()); cmdBuff.finish(); }
//============================================================================== void TextureResource::loadInternal(const CString& filename, ResourceInitializer& rinit) { GlDevice& gl = rinit.m_resources._getGlDevice(); GlCommandBufferHandle cmdb; cmdb.create(&gl); // Always first to avoid assertions ( // because of the check of the allocator) GlTextureHandle::Initializer init; U layers = 0; Bool driverShouldGenMipmaps = false; // Load image Image* imgPtr = rinit.m_alloc.newInstance<Image>(rinit.m_alloc); Image& img = *imgPtr; img.load(filename, rinit.m_resources.getMaxTextureSize()); // width + height init.m_width = img.getSurface(0, 0).m_width; init.m_height = img.getSurface(0, 0).m_height; // depth if(img.getTextureType() == Image::TextureType::_2D_ARRAY || img.getTextureType() == Image::TextureType::_3D) { init.m_depth = img.getDepth(); } else { init.m_depth = 0; } // target switch(img.getTextureType()) { case Image::TextureType::_2D: init.m_target = GL_TEXTURE_2D; layers = 1; break; case Image::TextureType::CUBE: init.m_target = GL_TEXTURE_CUBE_MAP; layers = 6; break; case Image::TextureType::_2D_ARRAY: init.m_target = GL_TEXTURE_2D_ARRAY; layers = init.m_depth; break; case Image::TextureType::_3D: init.m_target = GL_TEXTURE_3D; layers = init.m_depth; default: ANKI_ASSERT(0); } // Internal format if(img.getColorFormat() == Image::ColorFormat::RGB8) { switch(img.getCompression()) { case Image::DataCompression::RAW: #if DRIVER_CAN_COMPRESS init.m_internalFormat = GL_COMPRESSED_RGB; #else init.m_internalFormat = GL_RGB; #endif driverShouldGenMipmaps = true; break; #if ANKI_GL == ANKI_GL_DESKTOP case Image::DataCompression::S3TC: init.m_internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; #else case Image::DataCompression::ETC: init.m_internalFormat = GL_COMPRESSED_RGB8_ETC2; break; #endif default: ANKI_ASSERT(0); } } else if(img.getColorFormat() == Image::ColorFormat::RGBA8) { switch(img.getCompression()) { case Image::DataCompression::RAW: #if DRIVER_CAN_COMPRESS init.m_internalFormat = GL_COMPRESSED_RGBA; #else init.m_internalFormat = GL_RGBA; #endif driverShouldGenMipmaps = true; break; #if ANKI_GL == ANKI_GL_DESKTOP case Image::DataCompression::S3TC: init.m_internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; #else case Image::DataCompression::ETC: init.m_internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; break; #endif default: ANKI_ASSERT(0); } } else { ANKI_ASSERT(0); } // format switch(img.getColorFormat()) { case Image::ColorFormat::RGB8: init.m_format = GL_RGB; break; case Image::ColorFormat::RGBA8: init.m_format = GL_RGBA; break; default: ANKI_ASSERT(0); } // type init.m_type = GL_UNSIGNED_BYTE; // mipmapsCount init.m_mipmapsCount = img.getMipLevelsCount(); // filteringType init.m_filterType = GlTextureHandle::Filter::TRILINEAR; // repeat init.m_repeat = true; // anisotropyLevel init.m_anisotropyLevel = rinit.m_resources.getTextureAnisotropy(); // genMipmaps if(init.m_mipmapsCount == 1 || driverShouldGenMipmaps) { init.m_genMipmaps = true; } else { init.m_genMipmaps = false; } // Now assign the data for(U layer = 0; layer < layers; layer++) { for(U level = 0; level < init.m_mipmapsCount; level++) { GlClientBufferHandle& buff = init.m_data[level][layer]; buff.create( cmdb, img.getSurface(level, layer).m_data.size(), (void*)&img.getSurface(level, layer).m_data[0]); } } // Add the GL job to create the texture m_tex.create(cmdb, init); // Add cleanup job cmdb.pushBackUserCommand(deleteImageCallback, imgPtr); // Finaly enque the GL job chain cmdb.flush(); m_size = UVec3(init.m_width, init.m_height, init.m_depth); }
//============================================================================== void Ssao::initInternal(const ConfigSet& config) { m_enabled = config.get("pps.ssao.enabled"); if(!m_enabled) { return; } m_blurringIterationsCount = config.get("pps.ssao.blurringIterationsCount"); // // Init the widths/heights // const F32 quality = config.get("pps.ssao.renderingQuality"); m_width = quality * (F32)m_r->getWidth(); alignRoundUp(16, m_width); m_height = quality * (F32)m_r->getHeight(); alignRoundUp(16, m_height); // // create FBOs // createFb(m_hblurFb, m_hblurRt); createFb(m_vblurFb, m_vblurRt); // // noise texture // GlCommandBufferHandle cmdb; cmdb.create(&getGlDevice()); GlClientBufferHandle noise; noise.create( cmdb, sizeof(Vec3) * NOISE_TEX_SIZE * NOISE_TEX_SIZE, nullptr); genNoise((Vec3*)noise.getBaseAddress(), (Vec3*)((U8*)noise.getBaseAddress() + noise.getSize())); GlTextureHandle::Initializer tinit; tinit.m_width = tinit.m_height = NOISE_TEX_SIZE; tinit.m_target = GL_TEXTURE_2D; tinit.m_internalFormat = GL_RGB32F; tinit.m_format = GL_RGB; tinit.m_type = GL_FLOAT; tinit.m_filterType = GlTextureHandle::Filter::NEAREST; tinit.m_repeat = true; tinit.m_mipmapsCount = 1; tinit.m_data[0][0] = noise; m_noiseTex.create(cmdb, tinit); // // Kernel // String kernelStr(getAllocator()); Array<Vec3, KERNEL_SIZE> kernel; genKernel(kernel.begin(), kernel.end()); kernelStr = "vec3[]("; for(U i = 0; i < kernel.size(); i++) { String tmp(getAllocator()); tmp.sprintf("vec3(%f, %f, %f) %s", kernel[i].x(), kernel[i].y(), kernel[i].z(), (i != kernel.size() - 1) ? ", " : ")"); kernelStr += tmp; } // // Shaders // m_uniformsBuff.create(cmdb, GL_SHADER_STORAGE_BUFFER, sizeof(ShaderCommonUniforms), GL_DYNAMIC_STORAGE_BIT); String pps(getAllocator()); // main pass prog pps.sprintf( "#define NOISE_MAP_SIZE %u\n" "#define WIDTH %u\n" "#define HEIGHT %u\n" "#define KERNEL_SIZE %u\n" "#define KERNEL_ARRAY %s\n", NOISE_TEX_SIZE, m_width, m_height, KERNEL_SIZE, &kernelStr[0]); m_ssaoFrag.loadToCache(&getResourceManager(), "shaders/PpsSsao.frag.glsl", pps.toCString(), "r_"); m_ssaoPpline = m_r->createDrawQuadProgramPipeline( m_ssaoFrag->getGlProgram()); // blurring progs const char* SHADER_FILENAME = "shaders/VariableSamplingBlurGeneric.frag.glsl"; pps.sprintf( "#define HPASS\n" "#define COL_R\n" "#define IMG_DIMENSION %u\n" "#define SAMPLES 7\n", m_height); m_hblurFrag.loadToCache(&getResourceManager(), SHADER_FILENAME, pps.toCString(), "r_"); m_hblurPpline = m_r->createDrawQuadProgramPipeline( m_hblurFrag->getGlProgram()); pps.sprintf( "#define VPASS\n" "#define COL_R\n" "#define IMG_DIMENSION %u\n" "#define SAMPLES 7\n", m_width); m_vblurFrag.loadToCache(&getResourceManager(), SHADER_FILENAME, pps.toCString(), "r_"); m_vblurPpline = m_r->createDrawQuadProgramPipeline( m_vblurFrag->getGlProgram()); cmdb.flush(); }