/* Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. * * In no event and under no legal theory, whether in tort (including negligence), * contract, or otherwise, unless required by applicable law (such as deliberate * and grossly negligent acts) or agreed to in writing, shall any Contributor be * liable for any damages, including any direct, indirect, special, incidental, * or consequential damages of any character arising as a result of this License or * out of the use or inability to use the software (including but not limited to damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and * all other commercial damages or losses), even if such Contributor has been advised * of the possibility of such damages. */ // EngineSandbox.cpp : Defines the entry point for the application. // #include "pch.h" #include #include "TestTexturing.h" #include "GraphicsUtilities.h" #include "ShaderMacroHelper.h" using namespace Diligent; TestTexturing::TestTexturing() : UnitTestBase("Texturing test"), m_iTestTexWidth(512), m_iTestTexHeight(512), m_iMipLevels(8), m_TextureFormat(TEX_FORMAT_UNKNOWN) { } void TestTexturing::GenerateTextureData(IRenderDevice *pRenderDevice, std::vector &Data, std::vector &SubResouces, const TextureDesc &TexDesc, const float *ColorOffset) { Data.clear(); Uint32 CurrLevelOffset = 0; std::vector LevelDataOffsets(TexDesc.MipLevels); SubResouces.resize(TexDesc.MipLevels); auto PixelFormatAttribs = pRenderDevice->GetTextureFormatInfoExt(TexDesc.Format); auto PixelSize = Uint32{PixelFormatAttribs.ComponentSize} * Uint32{PixelFormatAttribs.NumComponents}; for(Uint32 Level = 0; Level < TexDesc.MipLevels; ++Level) { Uint32 MipWidth = TexDesc.Width >> Level; Uint32 MipHeight = TexDesc.Height >> Level; auto Stride = (MipWidth + 64) * PixelSize; Data.resize(Data.size() + size_t{Stride} * size_t{MipHeight}); auto *pCurrLevelPtr = &Data[CurrLevelOffset]; LevelDataOffsets[Level] = CurrLevelOffset; SubResouces[Level].Stride = Stride; for(Uint32 j=0; jGetDeviceCaps().DevType; bool bUseGLSL = DevType == DeviceType::OpenGL || DevType == DeviceType::OpenGLES || DevType == DeviceType::Vulkan; float Vertices[] = { 0, 0, 0, 0,1, 0, 1, 0, 0,0, 1, 0, 0, 1,1, 1, 1, 0, 1,0 }; for(int v=0; v < 4; ++v) { Vertices[v*5+0] = Vertices[v*5+0] * fXExtent + fMinXCoord; Vertices[v*5+1] = Vertices[v*5+1] * fYExtent + fMinYCoord; } { Diligent::BufferDesc BuffDesc; BuffDesc.uiSizeInBytes = sizeof(Vertices); BuffDesc.BindFlags = BIND_VERTEX_BUFFER; BuffDesc.Usage = USAGE_STATIC; Diligent::BufferData BuffData; BuffData.pData = Vertices; BuffData.DataSize = BuffDesc.uiSizeInBytes; m_pRenderDevice->CreateBuffer(BuffDesc, &BuffData, &m_pVertexBuff); } auto PixelFormatAttribs = m_pRenderDevice->GetTextureFormatInfoExt(m_TextureFormat); ShaderCreateInfo CreationAttrs; RefCntAutoPtr pShaderSourceFactory; pDevice->GetEngineFactory()->CreateDefaultShaderSourceStreamFactory("Shaders", &pShaderSourceFactory); CreationAttrs.pShaderSourceStreamFactory = pShaderSourceFactory; CreationAttrs.Desc.TargetProfile = bUseGLSL ? SHADER_PROFILE_GL_4_2 : SHADER_PROFILE_DX_5_0; CreationAttrs.UseCombinedTextureSamplers = true; RefCntAutoPtr pVS, pPS; { CreationAttrs.FilePath = bUseGLSL ? "Shaders\\TextureTestGL.vsh" : "Shaders\\TextureTestDX.vsh"; CreationAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX; m_pRenderDevice->CreateShader( CreationAttrs, &pVS ); } bool bIsIntTexture = false; { ShaderMacroHelper Macros; if (PixelFormatAttribs.ComponentType == COMPONENT_TYPE_UINT || PixelFormatAttribs.ComponentType == COMPONENT_TYPE_SINT) { if (bUseGLSL) { CreationAttrs.FilePath = "Shaders\\TextureIntTestGL.psh"; Macros.AddShaderMacro("SAMPLER_TYPE", PixelFormatAttribs.ComponentType == COMPONENT_TYPE_UINT ? "usampler2D" : "isampler2D"); } else { CreationAttrs.FilePath = "Shaders\\TextureIntTestDX.psh"; Macros.AddShaderMacro("DATA_TYPE", PixelFormatAttribs.ComponentType == COMPONENT_TYPE_UINT ? "uint4" : "int4"); } bIsIntTexture = true; } else { CreationAttrs.FilePath = bUseGLSL ? "Shaders\\TextureTestGL.psh" : "Shaders\\TextureTestDX.psh"; bIsIntTexture = false; } CreationAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL; CreationAttrs.Macros = Macros; m_pRenderDevice->CreateShader( CreationAttrs, &pPS ); } { SamplerDesc SamplerDesc; // On Intel HW, only point filtering sampler correctly works with an integer texture. // If the sampler defines linear filtering, the texture is not properly bound to the // sampler unit and zero is always returned. // Note that on NVidia HW this works fine. auto FilterType = bIsIntTexture ? FILTER_TYPE_POINT : FILTER_TYPE_LINEAR; SamplerDesc.MinFilter = FilterType; SamplerDesc.MagFilter = FilterType; SamplerDesc.MipFilter = FilterType; m_pRenderDevice->CreateSampler( SamplerDesc, &m_pSampler ); } { TextureDesc TexDesc; TexDesc.Type = RESOURCE_DIM_TEX_2D; TexDesc.Width = m_iTestTexWidth; TexDesc.Height = m_iTestTexHeight; TexDesc.MipLevels = m_iMipLevels; TexDesc.Usage = USAGE_STATIC; TexDesc.Format = m_TextureFormat; TexDesc.BindFlags = BIND_SHADER_RESOURCE; TexDesc.Name = "Test Texture"; std::vector Data; std::vector SubResouces; GenerateTextureData(m_pRenderDevice, Data, SubResouces, TexDesc); TextureData TexData; TexData.pSubResources = SubResouces.data(); TexData.NumSubresources = (Uint32)SubResouces.size(); m_pRenderDevice->CreateTexture( TexDesc, &TexData, &m_pTexture ); } { RefCntAutoPtr pDefaultSRV; TextureViewDesc ViewDesc; ViewDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; ViewDesc.NumMipLevels = TextureViewDesc::RemainingMipLevels; ViewDesc.NumArraySlices = TextureViewDesc::RemainingArraySlices; m_pTexture->CreateView( ViewDesc, &pDefaultSRV ); pDefaultSRV->SetSampler( m_pSampler ); ResourceMappingEntry Entries[] = { { "g_tex2DTest", pDefaultSRV }, {nullptr, nullptr} }; ResourceMappingDesc ResourceMapping; ResourceMapping.pEntries = Entries; m_pRenderDevice->CreateResourceMapping( ResourceMapping, &m_pResourceMapping ); } PipelineStateDesc PSODesc; PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = False; PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; PSODesc.GraphicsPipeline.BlendDesc.IndependentBlendEnable = False; PSODesc.GraphicsPipeline.BlendDesc.RenderTargets[0].BlendEnable = False; PSODesc.GraphicsPipeline.RTVFormats[0] = pSwapChain->GetDesc().ColorBufferFormat; PSODesc.GraphicsPipeline.DSVFormat = pSwapChain->GetDesc().DepthBufferFormat; PSODesc.GraphicsPipeline.NumRenderTargets = 1; PSODesc.GraphicsPipeline.pVS = pVS; PSODesc.GraphicsPipeline.pPS = pPS; PSODesc.GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; LayoutElement Elems[] = { LayoutElement{ 0, 0, 3, Diligent::VT_FLOAT32, false, 0 }, LayoutElement{ 1, 0, 2, Diligent::VT_FLOAT32, false, sizeof( float ) * 3 } }; PSODesc.GraphicsPipeline.InputLayout.LayoutElements = Elems; PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof( Elems ); StaticSamplerDesc StaticSampler; // On Intel HW, only point filtering sampler correctly works with an integer texture. // If the sampler defines linear filtering, the texture is not properly bound to the // sampler unit and zero is always returned. // Note that on NVidia HW this works fine. auto FilterType = bIsIntTexture ? FILTER_TYPE_POINT : FILTER_TYPE_LINEAR; StaticSampler.Desc.MinFilter = FilterType; StaticSampler.Desc.MagFilter = FilterType; StaticSampler.Desc.MipFilter = FilterType; StaticSampler.ShaderStages = SHADER_TYPE_PIXEL; StaticSampler.SamplerOrTextureName = "g_tex2DTest"; PSODesc.ResourceLayout.NumStaticSamplers = !(bIsIntTexture && pDevice->GetDeviceCaps().IsD3DDevice()) ? 1 : 0; PSODesc.ResourceLayout.StaticSamplers = &StaticSampler; pDevice->CreatePipelineState(PSODesc, &m_pPSO); m_pPSO->BindStaticResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, m_pResourceMapping, 0); m_pPSO->CreateShaderResourceBinding(&m_pSRB, true); auto *FmtName = pDevice->GetTextureFormatInfo(TexFormat).Name; m_TestName.append(" ("); m_TestName.append(FmtName); m_TestName.append(")"); } void TestTexturing::Draw() { m_pDeviceContext->SetPipelineState(m_pPSO); m_pDeviceContext->TransitionShaderResources(m_pPSO, m_pSRB); m_pDeviceContext->CommitShaderResources(m_pSRB, RESOURCE_STATE_TRANSITION_MODE_VERIFY); IBuffer *pBuffs[] = {m_pVertexBuff}; Uint32 Offsets[] = {0}; m_pDeviceContext->SetVertexBuffers( 0, 1, pBuffs, Offsets, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET ); // Draw quad Diligent::DrawAttribs DrawAttrs(4, DRAW_FLAG_VERIFY_ALL); m_pDeviceContext->Draw( DrawAttrs ); SetStatus(TestResult::Succeeded); }