void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool screenshot) { auto fb = GetVulkanFrameBuffer(); VkPPRenderState renderstate; if (!screenshot) // Already applied as we are actually copying the last frame here (GetScreenshotBuffer is called after swap) hw_postprocess.customShaders.Run(&renderstate, "screen"); PresentUniforms uniforms; if (!applyGamma) { uniforms.InvGamma = 1.0f; uniforms.Contrast = 1.0f; uniforms.Brightness = 0.0f; uniforms.Saturation = 1.0f; } else { uniforms.InvGamma = 1.0f / clamp<float>(Gamma, 0.1f, 4.f); uniforms.Contrast = clamp<float>(vid_contrast, 0.1f, 3.f); uniforms.Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f); uniforms.Saturation = clamp<float>(vid_saturation, -15.0f, 15.f); uniforms.GrayFormula = static_cast<int>(gl_satformula); } uniforms.ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1); if (screenshot) { uniforms.Scale = { screen->mScreenViewport.width / (float)fb->GetBuffers()->GetWidth(), screen->mScreenViewport.height / (float)fb->GetBuffers()->GetHeight() }; uniforms.Offset = { 0.0f, 0.0f }; } else { uniforms.Scale = { screen->mScreenViewport.width / (float)fb->GetBuffers()->GetWidth(), -screen->mScreenViewport.height / (float)fb->GetBuffers()->GetHeight() }; uniforms.Offset = { 0.0f, 1.0f }; } if (applyGamma && fb->swapChain->swapChainFormat.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT && !screenshot) { uniforms.HdrMode = 1; } else { uniforms.HdrMode = 0; } renderstate.Clear(); renderstate.Shader = &hw_postprocess.present.Present; renderstate.Uniforms.Set(uniforms); renderstate.Viewport = box; renderstate.SetInputCurrent(0, ViewportLinearScale() ? PPFilterMode::Linear : PPFilterMode::Nearest); renderstate.SetInputTexture(1, &hw_postprocess.present.Dither, PPFilterMode::Nearest, PPWrapMode::Repeat); if (screenshot) renderstate.SetOutputNext(); else renderstate.SetOutputSwapChain(); renderstate.SetNoBlend(); renderstate.Draw(); }
void VkPostprocess::AmbientOccludeScene(float m5) { auto fb = GetVulkanFrameBuffer(); int sceneWidth = fb->GetBuffers()->GetSceneWidth(); int sceneHeight = fb->GetBuffers()->GetSceneHeight(); VkPPRenderState renderstate; hw_postprocess.ssao.Render(&renderstate, m5, sceneWidth, sceneHeight); ImageTransitionScene(false); }
VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex) { if (!mDepthStencil.View) { auto fb = GetVulkanFrameBuffer(); VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat; int w = tex->GetWidth(); int h = tex->GetHeight(); ImageBuilder builder; builder.setSize(w, h); builder.setSamples(VK_SAMPLE_COUNT_1_BIT); builder.setFormat(format); builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); mDepthStencil.Image = builder.create(fb->device); mDepthStencil.Image->SetDebugName("VkHardwareTexture.DepthStencil"); mDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; ImageViewBuilder viewbuilder; viewbuilder.setImage(mDepthStencil.Image.get(), format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); mDepthStencil.View = viewbuilder.create(fb->device); mDepthStencil.View->SetDebugName("VkHardwareTexture.DepthStencilView"); VkImageTransition barrier; barrier.addImage(&mDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true); barrier.execute(fb->GetTransferCommands()); } return &mDepthStencil; }
void VkPostprocess::BlurScene(float gameinfobluramount) { auto fb = GetVulkanFrameBuffer(); int sceneWidth = fb->GetBuffers()->GetSceneWidth(); int sceneHeight = fb->GetBuffers()->GetSceneHeight(); VkPPRenderState renderstate; auto vrmode = VRMode::GetVRMode(true); int eyeCount = vrmode->mEyeCount; for (int i = 0; i < eyeCount; ++i) { hw_postprocess.bloom.RenderBlur(&renderstate, sceneWidth, sceneHeight, gameinfobluramount); if (eyeCount - i > 1) NextEye(eyeCount); } }
void VkPostprocess::BlitSceneToPostprocess() { auto fb = GetVulkanFrameBuffer(); fb->GetRenderState()->EndRenderPass(); auto buffers = fb->GetBuffers(); auto cmdbuffer = fb->GetDrawCommands(); mCurrentPipelineImage = 0; VkImageTransition imageTransition; imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false); imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); imageTransition.execute(fb->GetDrawCommands()); if (buffers->GetSceneSamples() != VK_SAMPLE_COUNT_1_BIT) { auto sceneColor = buffers->SceneColor.Image.get(); VkImageResolve resolve = {}; resolve.srcOffset = { 0, 0, 0 }; resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; resolve.srcSubresource.mipLevel = 0; resolve.srcSubresource.baseArrayLayer = 0; resolve.srcSubresource.layerCount = 1; resolve.dstOffset = { 0, 0, 0 }; resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; resolve.dstSubresource.mipLevel = 0; resolve.dstSubresource.baseArrayLayer = 0; resolve.dstSubresource.layerCount = 1; resolve.extent = { (uint32_t)sceneColor->width, (uint32_t)sceneColor->height, 1 }; cmdbuffer->resolveImage( sceneColor->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers->PipelineImage[mCurrentPipelineImage].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve); } else { auto sceneColor = buffers->SceneColor.Image.get(); VkImageBlit blit = {}; blit.srcOffsets[0] = { 0, 0, 0 }; blit.srcOffsets[1] = { sceneColor->width, sceneColor->height, 1 }; blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.srcSubresource.mipLevel = 0; blit.srcSubresource.baseArrayLayer = 0; blit.srcSubresource.layerCount = 1; blit.dstOffsets[0] = { 0, 0, 0 }; blit.dstOffsets[1] = { sceneColor->width, sceneColor->height, 1 }; blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.dstSubresource.mipLevel = 0; blit.dstSubresource.baseArrayLayer = 0; blit.dstSubresource.layerCount = 1; cmdbuffer->blitImage( sceneColor->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers->PipelineImage[mCurrentPipelineImage].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); } }
VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight) { auto fb = GetVulkanFrameBuffer(); VkTextureImage *tex = GetTexture(output.Type, output.Texture); VkImageView view; int w, h; if (tex) { VkImageTransition imageTransition; imageTransition.addImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture); if (stencilTest) imageTransition.addImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); imageTransition.execute(fb->GetDrawCommands()); view = tex->View->view; w = tex->Image->width; h = tex->Image->height; } else { view = fb->swapChain->swapChainImageViews[fb->presentImageIndex]; w = fb->swapChain->actualExtent.width; h = fb->swapChain->actualExtent.height; } auto &framebuffer = passSetup->Framebuffers[view]; if (!framebuffer) { FramebufferBuilder builder; builder.setRenderPass(passSetup->RenderPass.get()); builder.setSize(w, h); builder.addAttachment(view); if (stencilTest) builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get()); framebuffer = builder.create(GetVulkanFrameBuffer()->device); } framebufferWidth = w; framebufferHeight = h; return framebuffer.get(); }
void VkPostprocess::SetActiveRenderTarget() { auto fb = GetVulkanFrameBuffer(); auto buffers = fb->GetBuffers(); VkImageTransition imageTransition; imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false); imageTransition.execute(fb->GetDrawCommands()); fb->GetRenderState()->SetRenderTarget(buffers->PipelineImage[mCurrentPipelineImage].View.get(), nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT); }
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) { auto fb = GetVulkanFrameBuffer(); int sceneWidth = fb->GetBuffers()->GetSceneWidth(); int sceneHeight = fb->GetBuffers()->GetSceneHeight(); VkPPRenderState renderstate; hw_postprocess.exposure.Render(&renderstate, sceneWidth, sceneHeight); hw_postprocess.customShaders.Run(&renderstate, "beforebloom"); hw_postprocess.bloom.RenderBloom(&renderstate, sceneWidth, sceneHeight, fixedcm); SetActiveRenderTarget(); afterBloomDrawEndScene2D(); hw_postprocess.tonemap.Render(&renderstate); hw_postprocess.colormap.Render(&renderstate, fixedcm); hw_postprocess.lens.Render(&renderstate); hw_postprocess.fxaa.Render(&renderstate); hw_postprocess.customShaders.Run(&renderstate, "scene"); }
void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout) { auto fb = GetVulkanFrameBuffer(); auto buffers = fb->GetBuffers(); VkImageTransition imageTransition; imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.addImage(&buffers->SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.addImage(&buffers->SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.addImage(&buffers->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.execute(fb->GetDrawCommands()); }
void VkPPRenderState::Draw() { auto fb = GetVulkanFrameBuffer(); auto pp = fb->GetPostprocess(); fb->GetRenderState()->EndRenderPass(); VkPPRenderPassKey key; key.BlendMode = BlendMode; key.InputTextures = Textures.Size(); key.Uniforms = Uniforms.Data.Size(); key.Shader = GetVkShader(Shader); key.SwapChain = (Output.Type == PPTextureType::SwapChain); key.ShadowMapBuffers = ShadowMapBuffers; if (Output.Type == PPTextureType::PPTexture) key.OutputFormat = GetVkTexture(Output.Texture)->Format; else if (Output.Type == PPTextureType::SwapChain) key.OutputFormat = GetVulkanFrameBuffer()->swapChain->swapChainFormat.format; else if (Output.Type == PPTextureType::ShadowMap) key.OutputFormat = VK_FORMAT_R32_SFLOAT; else key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT; if (Output.Type == PPTextureType::SceneColor) { key.StencilTest = 1; key.Samples = fb->GetBuffers()->GetSceneSamples(); } else { key.StencilTest = 0; key.Samples = VK_SAMPLE_COUNT_1_BIT; } auto &passSetup = pp->mRenderPassSetup[key]; if (!passSetup) passSetup.reset(new VkPPRenderPassSetup(key)); int framebufferWidth = 0, framebufferHeight = 0; VulkanDescriptorSet *input = GetInput(passSetup.get(), Textures, ShadowMapBuffers); VulkanFramebuffer *output = GetOutput(passSetup.get(), Output, key.StencilTest, framebufferWidth, framebufferHeight); RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest); // Advance to next PP texture if our output was sent there if (Output.Type == PPTextureType::NextPipelineTexture) { pp->mCurrentPipelineImage = (pp->mCurrentPipelineImage + 1) % VkRenderBuffers::NumPipelineImages; } }
ECode CMediaCodec::GetOutputBuffers( /* [out] */ ArrayOf<IByteBuffer*>** result) { VALIDATE_NOT_NULL(result); *result = NULL; if (mCodec == NULL) { return E_ILLEGAL_STATE_EXCEPTION; } AutoPtr<ArrayOf<IByteBuffer*> > temp; GetBuffers(FALSE /* input */, (ArrayOf<IByteBuffer*>**)&temp); *result = temp; REFCOUNT_ADD(*result); return NOERROR; }
void VkPostprocess::UpdateShadowMap() { if (screen->mShadowMap.PerformUpdate()) { VkPPRenderState renderstate; hw_postprocess.shadowmap.Update(&renderstate); auto fb = GetVulkanFrameBuffer(); auto buffers = fb->GetBuffers(); VkImageTransition imageTransition; imageTransition.addImage(&buffers->Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); imageTransition.execute(fb->GetDrawCommands()); screen->mShadowMap.FinishUpdate(); } }
VkTextureImage *VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture *pptexture) { auto fb = GetVulkanFrameBuffer(); if (type == PPTextureType::CurrentPipelineTexture || type == PPTextureType::NextPipelineTexture) { int idx = fb->GetPostprocess()->mCurrentPipelineImage; if (type == PPTextureType::NextPipelineTexture) idx = (idx + 1) % VkRenderBuffers::NumPipelineImages; return &fb->GetBuffers()->PipelineImage[idx]; } else if (type == PPTextureType::PPTexture) { auto vktex = GetVkTexture(pptexture); return &vktex->TexImage; } else if (type == PPTextureType::SceneColor) { return &fb->GetBuffers()->SceneColor; } else if (type == PPTextureType::SceneNormal) { return &fb->GetBuffers()->SceneNormal; } else if (type == PPTextureType::SceneFog) { return &fb->GetBuffers()->SceneFog; } else if (type == PPTextureType::SceneDepth) { return &fb->GetBuffers()->SceneDepthStencil; } else if (type == PPTextureType::ShadowMap) { return &fb->GetBuffers()->Shadowmap; } else if (type == PPTextureType::SwapChain) { return nullptr; } else { I_FatalError("VkPPRenderState::GetTexture not implemented yet for this texture type"); return nullptr; } }
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout) { auto fb = GetVulkanFrameBuffer(); fb->GetRenderState()->EndRenderPass(); auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage]; auto cmdbuffer = fb->GetDrawCommands(); VkImageTransition imageTransition0; imageTransition0.addImage(srcimage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false); imageTransition0.addImage(dstimage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); imageTransition0.execute(cmdbuffer); VkImageBlit blit = {}; blit.srcOffsets[0] = { 0, 0, 0 }; blit.srcOffsets[1] = { srcimage->Image->width, srcimage->Image->height, 1 }; blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.srcSubresource.mipLevel = 0; blit.srcSubresource.baseArrayLayer = 0; blit.srcSubresource.layerCount = 1; blit.dstOffsets[0] = { 0, 0, 0 }; blit.dstOffsets[1] = { dstimage->Image->width, dstimage->Image->height, 1 }; blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.dstSubresource.mipLevel = 0; blit.dstSubresource.baseArrayLayer = 0; blit.dstSubresource.layerCount = 1; cmdbuffer->blitImage( srcimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); VkImageTransition imageTransition1; imageTransition1.addImage(dstimage, finallayout, false); imageTransition1.execute(cmdbuffer); }