TextureTargetPtr TextureSystem::CreateTarget(const TextureTarget::Params& params) { ComPtr<ID3D11Resource> d3dResource; if (params.depth > 0) { D3D11_TEXTURE3D_DESC desc; desc.Width = params.width; desc.Height = params.height; desc.Depth = params.depth; desc.MipLevels = params.lastMip+1; desc.Format = TranslateFormat((TextureTarget::Format)params.format); desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.BindFlags |= IsDepthFormat((TextureTarget::Format)params.format) ? D3D11_BIND_DEPTH_STENCIL : 0; desc.CPUAccessFlags = (params.flags & TextureTarget::cFlag_CpuReadAccess) ? D3D11_CPU_ACCESS_READ : 0; desc.MiscFlags = 0; HRESULT hr = EngineCore::s_instance.device->CreateTexture3D(&desc, nullptr, (ID3D11Texture3D**) d3dResource.GetAddressOf()); if (FAILED(hr)) return nullptr; } else { D3D11_TEXTURE2D_DESC desc; desc.Width = params.width; desc.Height = params.height; desc.MipLevels = params.lastMip+1; desc.ArraySize = params.arrayLength > 0 ? params.arrayLength : 1; desc.Format = TranslateFormat((TextureTarget::Format)params.format); desc.SampleDesc.Count = 1 << params.multisampling; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.BindFlags |= IsDepthFormat((TextureTarget::Format)params.format) ? D3D11_BIND_DEPTH_STENCIL : 0; desc.CPUAccessFlags = (params.flags & TextureTarget::cFlag_CpuReadAccess) ? D3D11_CPU_ACCESS_READ : 0; desc.MiscFlags = 0; HRESULT hr = EngineCore::s_instance.device->CreateTexture2D(&desc, nullptr, (ID3D11Texture2D**) d3dResource.GetAddressOf()); if (FAILED(hr)) return nullptr; } Texture::Details* details = new(g_texturePool.Allocate()) Texture::Details((Texture::Params&)params); assert(details != nullptr); details->m_d3dResource.Swap(d3dResource); return (TextureTarget*)details; }
void OGLESTextureCubeDepthStencilRenderView::OnAttached(FrameBuffer& fb, uint32_t att) { UNREF_PARAM(att); BOOST_ASSERT(FrameBuffer::ATT_DepthStencil == att); index_ = 0; fbo_ = checked_cast<OGLESFrameBuffer*>(&fb)->OGLFbo(); GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face_ - Texture::CF_Positive_X; OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindFramebuffer(fbo_); if (IsDepthFormat(pf_)) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, face, tex_, level_); } if (IsStencilFormat(pf_)) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, face, tex_, level_); } re.BindFramebuffer(0); }
OGLESDepthStencilRenderView::OGLESDepthStencilRenderView(uint32_t width, uint32_t height, ElementFormat pf, uint32_t sample_count, uint32_t sample_quality) : target_type_(0), array_index_(0), level_(-1), sample_count_(sample_count), sample_quality_(sample_quality) { BOOST_ASSERT(IsDepthFormat(pf)); width_ = width; height_ = height; pf_ = pf; GLint internalFormat; GLenum glformat; GLenum gltype; OGLESMapping::MappingFormat(internalFormat, glformat, gltype, pf_); switch (internalFormat) { case GL_DEPTH_COMPONENT: internalFormat = GL_DEPTH_COMPONENT16; break; case GL_DEPTH_STENCIL_OES: internalFormat = GL_DEPTH24_STENCIL8_OES; break; default: break; } glGenRenderbuffers(1, &rbo_); glBindRenderbuffer(GL_RENDERBUFFER, rbo_); glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width_, height_); }
std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config) { // Use typeless to create the texture when it's a render target, so we can alias it with an // integer format (for EFB). const DXGI_FORMAT tex_format = D3DCommon::GetDXGIFormatForAbstractFormat(config.format, config.IsRenderTarget()); UINT bindflags = D3D11_BIND_SHADER_RESOURCE; if (config.IsRenderTarget()) bindflags |= IsDepthFormat(config.format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; if (config.IsComputeImage()) bindflags |= D3D11_BIND_UNORDERED_ACCESS; CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels, bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, 0); ComPtr<ID3D11Texture2D> d3d_texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &d3d_texture); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D backing texture", config.width, config.height, config.layers); return nullptr; } std::unique_ptr<DXTexture> tex(new DXTexture(config, d3d_texture.Get())); if (!tex->CreateSRV() || (config.IsComputeImage() && !tex->CreateUAV())) return nullptr; return tex; }
OGLESScreenDepthStencilRenderView::OGLESScreenDepthStencilRenderView(uint32_t width, uint32_t height, ElementFormat pf) { BOOST_ASSERT(IsDepthFormat(pf)); width_ = width; height_ = height; pf_ = pf; }
void DoSerialise(SerialiserType &ser, D3D12_CLEAR_VALUE &el) { SERIALISE_MEMBER(Format); if(IsDepthFormat(el.Format)) SERIALISE_MEMBER(DepthStencil); else SERIALISE_MEMBER(Color); }
std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config) { // Use typeless to create the texture when it's a render target, so we can alias it with an // integer format (for EFB). const DXGI_FORMAT tex_format = GetDXGIFormatForHostFormat(config.format, config.IsRenderTarget()); const DXGI_FORMAT srv_format = GetSRVFormatForHostFormat(config.format); UINT bindflags = D3D11_BIND_SHADER_RESOURCE; if (config.IsRenderTarget()) bindflags |= IsDepthFormat(config.format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; if (config.IsComputeImage()) bindflags |= D3D11_BIND_UNORDERED_ACCESS; CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels, bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, 0); ID3D11Texture2D* d3d_texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &d3d_texture); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D backing texture", config.width, config.height, config.layers); return nullptr; } ID3D11ShaderResourceView* d3d_srv; const CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(d3d_texture, config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D11_SRV_DIMENSION_TEXTURE2DARRAY, srv_format, 0, config.levels, 0, config.layers); hr = D3D::device->CreateShaderResourceView(d3d_texture, &srv_desc, &d3d_srv); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D SRV", config.width, config.height, config.layers); d3d_texture->Release(); return nullptr; } ID3D11UnorderedAccessView* d3d_uav = nullptr; if (config.IsComputeImage()) { const CD3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc( d3d_texture, D3D11_UAV_DIMENSION_TEXTURE2DARRAY, srv_format, 0, 0, config.layers); hr = D3D::device->CreateUnorderedAccessView(d3d_texture, &uav_desc, &d3d_uav); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D UAV", config.width, config.height, config.layers); d3d_uav->Release(); d3d_texture->Release(); return nullptr; } } return std::make_unique<DXTexture>(config, d3d_texture, d3d_srv, d3d_uav); }
inline UINT TranslateBindFlags(Texture::Usage usage, Format format) { UINT bind = D3D11_BIND_SHADER_RESOURCE; if (usage == Texture::Usage::RenderTarget) { bind |= D3D11_BIND_RENDER_TARGET; bind |= IsDepthFormat(format) ? D3D11_BIND_DEPTH_STENCIL : 0; } return bind; }
void OGLESRenderView::ClearDepthStencil(float depth, int32_t stencil) { uint32_t flags = 0; if (IsDepthFormat(pf_)) { flags |= GL_DEPTH_BUFFER_BIT; } if (IsStencilFormat(pf_)) { flags |= GL_STENCIL_BUFFER_BIT; } this->DoClear(flags, Color(), depth, stencil); }
void OGLESDepthStencilRenderView::OnAttached(FrameBuffer& fb, uint32_t att) { UNREF_PARAM(att); BOOST_ASSERT(FrameBuffer::ATT_DepthStencil == att); index_ = 0; fbo_ = checked_cast<OGLESFrameBuffer*>(&fb)->OGLFbo(); if (level_ < 0) { OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindFramebuffer(fbo_); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_); if (IsStencilFormat(pf_)) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo_); } re.BindFramebuffer(0); } else { OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); BOOST_ASSERT(GL_TEXTURE_2D == target_type_); re.BindFramebuffer(fbo_); if (IsDepthFormat(pf_)) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target_type_, tex_, level_); } if (IsStencilFormat(pf_)) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, target_type_, tex_, level_); } re.BindFramebuffer(0); } }
OGLESDepthStencilRenderView::OGLESDepthStencilRenderView(Texture& texture, int array_index, int level) : target_type_(checked_cast<OGLESTexture2D*>(&texture)->GLType()), array_index_(array_index), level_(level) { BOOST_ASSERT(Texture::TT_2D == texture.Type()); BOOST_ASSERT(IsDepthFormat(texture.Format())); if (array_index > 0) { THR(errc::function_not_supported); } width_ = texture.Width(level); height_ = texture.Height(level); pf_ = texture.Format(); tex_ = checked_cast<OGLESTexture2D*>(&texture)->GLTexture(); }
OGLESTextureCubeDepthStencilRenderView::OGLESTextureCubeDepthStencilRenderView(Texture& texture_cube, int array_index, Texture::CubeFaces face, int level) : texture_cube_(*checked_cast<OGLESTextureCube*>(&texture_cube)), face_(face), level_(level) { BOOST_ASSERT(Texture::TT_Cube == texture_cube.Type()); BOOST_ASSERT(IsDepthFormat(texture_cube.Format())); if (array_index > 0) { THR(errc::function_not_supported); } width_ = texture_cube.Width(level); height_ = texture_cube.Height(level); pf_ = texture_cube.Format(); tex_ = checked_cast<OGLESTextureCube*>(&texture_cube)->GLTexture(); }
void D3D12TextureCube::BuildMipSubLevels() { // TODO // Depth stencil formats // Compression formats if (IsDepthFormat(format_) || IsCompressedFormat(format_)) { for (uint32_t index = 0; index < this->ArraySize(); ++ index) { for (int f = 0; f < 6; ++ f) { CubeFaces const face = static_cast<CubeFaces>(f); for (uint32_t level = 1; level < this->NumMipMaps(); ++ level) { this->ResizeTextureCube(*this, index, face, level, 0, 0, this->Width(level), this->Height(level), index, face, level - 1, 0, 0, this->Width(level - 1), this->Height(level - 1), true); } } } } else { D3D12RenderEngine& re = *checked_cast<D3D12RenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); ID3D12Device*device = re.D3DDevice(); ID3D12GraphicsCommandList* cmd_list = re.D3DRenderCmdList(); auto const & effect = *re.BlitEffect(); auto const & tech = *re.BilinearBlitTech(); auto& pass = tech.Pass(0); pass.Bind(effect); D3D12ShaderObject& d3d12_so = *checked_cast<D3D12ShaderObject*>(pass.GetShaderObject(effect).get()); D3D12RenderLayout& d3d12_rl = *checked_cast<D3D12RenderLayout*>(re.PostProcessRenderLayout().get()); D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc; d3d12_so.UpdatePsoDesc(pso_desc); pso_desc.StreamOutput.pSODeclaration = nullptr; pso_desc.StreamOutput.NumEntries = 0; pso_desc.StreamOutput.pBufferStrides = nullptr; pso_desc.StreamOutput.NumStrides = 0; pso_desc.StreamOutput.RasterizedStream = 0; pso_desc.BlendState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DBlendDesc(); pso_desc.SampleMask = 0xFFFFFFFF; pso_desc.RasterizerState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DRasterizerDesc(); pso_desc.DepthStencilState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DDepthStencilDesc(); pso_desc.InputLayout.pInputElementDescs = &d3d12_rl.InputElementDesc()[0]; pso_desc.InputLayout.NumElements = static_cast<UINT>(d3d12_rl.InputElementDesc().size()); pso_desc.IBStripCutValue = (EF_R16UI == d3d12_rl.IndexStreamFormat()) ? D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF : D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; RenderLayout::topology_type tt = d3d12_rl.TopologyType(); pso_desc.PrimitiveTopologyType = D3D12Mapping::MappingPriTopoType(tt); pso_desc.NumRenderTargets = 1; pso_desc.RTVFormats[0] = dxgi_fmt_; for (uint32_t i = pso_desc.NumRenderTargets; i < std::size(pso_desc.RTVFormats); ++ i) { pso_desc.RTVFormats[i] = DXGI_FORMAT_UNKNOWN; } pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN; pso_desc.SampleDesc.Count = 1; pso_desc.SampleDesc.Quality = 0; pso_desc.NodeMask = 0; pso_desc.CachedPSO.pCachedBlob = nullptr; pso_desc.CachedPSO.CachedBlobSizeInBytes = 0; pso_desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; ID3D12PipelineStatePtr const & pso = re.CreateRenderPSO(pso_desc); re.SetPipelineState(pso.get()); re.SetGraphicsRootSignature(d3d12_so.RootSignature()); ID3D12DescriptorHeapPtr cbv_srv_uav_heap = re.CreateDynamicCBVSRVUAVDescriptorHeap(array_size_ * 6 * (num_mip_maps_ - 1)); auto sampler_heap = d3d12_so.SamplerHeap(); std::array<ID3D12DescriptorHeap*, 2> heaps; uint32_t num_heaps = 0; { heaps[num_heaps] = cbv_srv_uav_heap.get(); ++ num_heaps; } if (sampler_heap) { heaps[num_heaps] = sampler_heap; ++ num_heaps; } re.SetDescriptorHeaps(ArrayRef<ID3D12DescriptorHeap*>(heaps.data(), num_heaps)); if (sampler_heap) { D3D12_GPU_DESCRIPTOR_HANDLE gpu_sampler_handle = sampler_heap->GetGPUDescriptorHandleForHeapStart(); cmd_list->SetGraphicsRootDescriptorTable(1, gpu_sampler_handle); } D3D12GraphicsBuffer& vb = *checked_cast<D3D12GraphicsBuffer*>(d3d12_rl.GetVertexStream(0).get()); D3D12_VERTEX_BUFFER_VIEW vbv; vbv.BufferLocation = vb.GPUVirtualAddress(); vbv.SizeInBytes = vb.Size(); vbv.StrideInBytes = d3d12_rl.VertexSize(0); re.IASetVertexBuffers(0, vbv); re.IASetPrimitiveTopology(tt); D3D12_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; vp.MinDepth = 0; vp.MaxDepth = 1; D3D12_RECT scissor_rc; scissor_rc.left = 0; scissor_rc.top = 0; D3D12_RESOURCE_BARRIER barrier; barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; D3D12_CPU_DESCRIPTOR_HANDLE cpu_cbv_srv_uav_handle = cbv_srv_uav_heap->GetCPUDescriptorHandleForHeapStart(); D3D12_GPU_DESCRIPTOR_HANDLE gpu_cbv_srv_uav_handle = cbv_srv_uav_heap->GetGPUDescriptorHandleForHeapStart(); uint32_t const srv_desc_size = re.CBVSRVUAVDescSize(); for (uint32_t index = 0; index < array_size_; ++ index) { for (int f = 0; f < 6; ++ f) { for (uint32_t level = 1; level < num_mip_maps_; ++ level) { cmd_list->SetGraphicsRootDescriptorTable(0, gpu_cbv_srv_uav_handle); UINT n = 0; D3D12_RESOURCE_BARRIER barriers[2]; if (this->UpdateResourceBarrier(CalcSubresource(level - 1, index * 6 + f, 0, num_mip_maps_, array_size_), barrier, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)) { barriers[n] = barrier; ++ n; } if (this->UpdateResourceBarrier(CalcSubresource(level, index * 6 + f, 0, num_mip_maps_, array_size_), barrier, D3D12_RESOURCE_STATE_RENDER_TARGET)) { barriers[n] = barrier; ++ n; } if (n > 0) { cmd_list->ResourceBarrier(n, barriers); } D3D12_CPU_DESCRIPTOR_HANDLE const & rt_handle = this->RetriveD3DRenderTargetView(index * 6 + f, 1, level)->Handle(); D3D12_CPU_DESCRIPTOR_HANDLE const & sr_handle = this->RetriveD3DShaderResourceView(index * 6 + f, 1, level - 1, 1)->Handle(); device->CopyDescriptorsSimple(1, cpu_cbv_srv_uav_handle, sr_handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); cmd_list->OMSetRenderTargets(1, &rt_handle, false, nullptr); vp.Width = static_cast<float>(this->Width(level)); vp.Height = static_cast<float>(this->Height(level)); re.RSSetViewports(1, &vp); scissor_rc.right = this->Width(level); scissor_rc.bottom = this->Height(level); re.RSSetScissorRects(scissor_rc); cmd_list->DrawInstanced(4, 1, 0, 0); cpu_cbv_srv_uav_handle.ptr += srv_desc_size; gpu_cbv_srv_uav_handle.ptr += srv_desc_size; } } } pass.Unbind(effect); auto& fb = *checked_cast<D3D12FrameBuffer*>(re.CurFrameBuffer().get()); fb.SetRenderTargets(); } }
void D3D11Texture::GetD3DFlags(D3D11_USAGE& usage, UINT& bind_flags, UINT& cpu_access_flags, UINT& misc_flags) { if (access_hint_ & EAH_Immutable) { usage = D3D11_USAGE_IMMUTABLE; } else { if ((EAH_CPU_Write | EAH_GPU_Read) == access_hint_) { usage = D3D11_USAGE_DYNAMIC; } else { if (EAH_CPU_Write == access_hint_) { if ((num_mip_maps_ != 1) || (TT_Cube == type_)) { usage = D3D11_USAGE_STAGING; } else { usage = D3D11_USAGE_DYNAMIC; } } else { if (!(access_hint_ & EAH_CPU_Read) && !(access_hint_ & EAH_CPU_Write)) { usage = D3D11_USAGE_DEFAULT; } else { usage = D3D11_USAGE_STAGING; } } } } bind_flags = 0; if ((access_hint_ & EAH_GPU_Read) || (D3D11_USAGE_DYNAMIC == usage)) { bind_flags |= D3D11_BIND_SHADER_RESOURCE; } if (access_hint_ & EAH_GPU_Write) { if (IsDepthFormat(format_)) { bind_flags |= D3D11_BIND_DEPTH_STENCIL; } else { bind_flags |= D3D11_BIND_RENDER_TARGET; } } D3D11RenderEngine const & re = *checked_cast<D3D11RenderEngine const *>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (re.DeviceFeatureLevel() >= D3D_FEATURE_LEVEL_11_0) { if (access_hint_ & EAH_GPU_Unordered) { bind_flags |= D3D11_BIND_UNORDERED_ACCESS; } } cpu_access_flags = 0; if (access_hint_ & EAH_CPU_Read) { cpu_access_flags |= D3D11_CPU_ACCESS_READ; } if (access_hint_ & EAH_CPU_Write) { cpu_access_flags |= D3D11_CPU_ACCESS_WRITE; } misc_flags = 0; if (access_hint_ & EAH_Generate_Mips) { misc_flags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; } }
void OGLESFrameBuffer::Clear(uint32_t flags, Color const & clr, float depth, int32_t stencil) { OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); GLuint old_fbo = re.BindFramebuffer(); re.BindFramebuffer(fbo_); bool has_color = (flags & CBM_Color) && !!this->Attached(ATT_Color0); bool has_depth = false; bool has_stencil = false; RenderViewPtr const & ds_view = this->Attached(ATT_DepthStencil); if (ds_view) { has_depth = (flags & CBM_Depth) && IsDepthFormat(ds_view->Format()); has_stencil = (flags & CBM_Stencil) && IsStencilFormat(ds_view->Format()); } DepthStencilStateDesc const & ds_desc = re.CurDSSObj()->GetDesc(); BlendStateDesc const & blend_desc = re.CurBSObj()->GetDesc(); if (has_color) { if (blend_desc.color_write_mask[0] != CMASK_All) { glColorMask(true, true, true, true); } } if (has_depth) { if (!ds_desc.depth_write_mask) { glDepthMask(GL_TRUE); } } if (has_stencil) { if (ds_desc.front_stencil_write_mask != 0xFF) { glStencilMaskSeparate(GL_FRONT, 0xFF); } if (ds_desc.back_stencil_write_mask != 0xFF) { glStencilMaskSeparate(GL_BACK, 0xFF); } } if (glloader_GLES_VERSION_3_0()) { if (flags & CBM_Color) { if (fbo_ != 0) { for (size_t i = 0; i < clr_views_.size(); ++ i) { if (clr_views_[i]) { glClearBufferfv(GL_COLOR, static_cast<GLint>(i), &clr[0]); } } } else { glClearBufferfv(GL_COLOR, 0, &clr[0]); } } if (has_depth && has_stencil) { glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil); } else { if (has_depth) { glClearBufferfv(GL_DEPTH, 0, &depth); } else if (has_stencil) { GLint s = stencil; glClearBufferiv(GL_STENCIL, 0, &s); } } } else { GLbitfield ogl_flags = 0; if (has_color) { ogl_flags |= GL_COLOR_BUFFER_BIT; re.ClearColor(clr.r(), clr.g(), clr.b(), clr.a()); } if (has_depth) { ogl_flags |= GL_DEPTH_BUFFER_BIT; re.ClearDepth(depth); } if (has_stencil) { ogl_flags |= GL_STENCIL_BUFFER_BIT; re.ClearStencil(stencil); } glClear(ogl_flags); } if (flags & CBM_Color) { if (blend_desc.color_write_mask[0] != CMASK_All) { glColorMask((blend_desc.color_write_mask[0] & CMASK_Red) != 0, (blend_desc.color_write_mask[0] & CMASK_Green) != 0, (blend_desc.color_write_mask[0] & CMASK_Blue) != 0, (blend_desc.color_write_mask[0] & CMASK_Alpha) != 0); } } if (has_depth) { if (!ds_desc.depth_write_mask) { glDepthMask(GL_FALSE); } } if (has_stencil) { if (ds_desc.front_stencil_write_mask != 0xFF) { glStencilMaskSeparate(GL_FRONT, ds_desc.front_stencil_write_mask); } if (ds_desc.back_stencil_write_mask != 0xFF) { glStencilMaskSeparate(GL_BACK, ds_desc.back_stencil_write_mask); } } re.BindFramebuffer(old_fbo); }
bool DataFormat::IsDepthFormat() const { return IsDepthFormat(type); }