summaryrefslogtreecommitdiffstats
path: root/Tests/TestApp/src/TestTexturing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/TestApp/src/TestTexturing.cpp')
-rw-r--r--Tests/TestApp/src/TestTexturing.cpp285
1 files changed, 285 insertions, 0 deletions
diff --git a/Tests/TestApp/src/TestTexturing.cpp b/Tests/TestApp/src/TestTexturing.cpp
new file mode 100644
index 0000000..69f0a49
--- /dev/null
+++ b/Tests/TestApp/src/TestTexturing.cpp
@@ -0,0 +1,285 @@
+/* Copyright 2015-2017 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 <math.h>
+#include "TestTexturing.h"
+#include "GraphicsUtilities.h"
+#include "BasicShaderSourceStreamFactory.h"
+
+using namespace Diligent;
+
+TestTexturing::TestTexturing() :
+ m_iTestTexWidth(512),
+ m_iTestTexHeight(512),
+ m_iMipLevels(8),
+ m_TextureFormat(TEX_FORMAT_UNKNOWN)
+{
+}
+
+void TestTexturing::GenerateTextureData(IRenderDevice *pRenderDevice, std::vector<Uint8> &Data, std::vector<TextureSubResData> &SubResouces, const TextureDesc &TexDesc, const float *ColorOffset)
+{
+ Data.clear();
+ Uint32 CurrLevelOffset = 0;
+ std::vector<Uint32> LevelDataOffsets(TexDesc.MipLevels);
+ SubResouces.resize(TexDesc.MipLevels);
+
+ auto PixelFormatAttribs = pRenderDevice->GetTextureFormatInfoExt(TexDesc.Format);
+ auto PixelSize = PixelFormatAttribs.ComponentSize * 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() + Stride * MipHeight);
+ auto *pCurrLevelPtr = &Data[CurrLevelOffset];
+ LevelDataOffsets[Level] = CurrLevelOffset;
+ SubResouces[Level].Stride = Stride;
+ for(Uint32 j=0; j<MipHeight; ++j)
+ for(Uint32 i=0; i<MipWidth; ++i)
+ {
+ float Color[4] =
+ {
+ (float)i/(float)MipWidth * 1.5f + (ColorOffset ? ColorOffset[0] : 0.f),
+ (float)j/(float)MipHeight * 1.7f+ (ColorOffset ? ColorOffset[1] : 0.f),
+ (float)j/(float)MipHeight / 1.3f + (float)i/(float)MipWidth/1.1f + (ColorOffset ? ColorOffset[2] : 0.f),
+ 1.f + (ColorOffset ? ColorOffset[3] : 0.f)
+ };
+ for(Uint32 iCmp = 0; iCmp < PixelFormatAttribs.NumComponents; ++iCmp)
+ {
+ float fCurrCmpCol = Color[iCmp];
+ fCurrCmpCol = fCurrCmpCol - floor(fCurrCmpCol);
+ void *pDstCmp = pCurrLevelPtr + (i*PixelSize + iCmp * PixelFormatAttribs.ComponentSize + j*Stride);
+ switch(PixelFormatAttribs.ComponentType)
+ {
+ case COMPONENT_TYPE_FLOAT:
+ *((float*)pDstCmp) = fCurrCmpCol;
+ break;
+
+ case COMPONENT_TYPE_SNORM:
+ if( PixelFormatAttribs.ComponentSize == 1 )
+ *((Int8*)pDstCmp) = (Int8) std::min( std::max(fCurrCmpCol*127.f, -127.f), 127.f );
+ else if( PixelFormatAttribs.ComponentSize == 2 )
+ *((Int16*)pDstCmp) = (Int16) std::min( std::max(fCurrCmpCol*32767.f, -32767.f), 32767.f );
+ else
+ assert(false);
+ break;
+
+ case COMPONENT_TYPE_UNORM_SRGB:
+ case COMPONENT_TYPE_UNORM:
+ if( PixelFormatAttribs.ComponentSize == 1 )
+ *((Uint8*)pDstCmp) = (Uint8) std::min( std::max(fCurrCmpCol*255,0.f), 255.f );
+ else if( PixelFormatAttribs.ComponentSize == 2 )
+ *((Uint16*)pDstCmp) = (Uint16) std::min( std::max(fCurrCmpCol*65535.f,0.f), 65535.f );
+ else
+ assert(false);
+ break;
+
+ case COMPONENT_TYPE_SINT:
+ if( PixelFormatAttribs.ComponentSize == 1 )
+ *((Int8*)pDstCmp) = (Int8) std::min( std::max(fCurrCmpCol*127.f, -127.f), 127.f );
+ else if( PixelFormatAttribs.ComponentSize == 2 )
+ *((Int16*)pDstCmp) = (Int16) std::min( std::max(fCurrCmpCol*127.f, -127.f), 127.f );
+ else
+ assert(false);
+ break;
+
+ case COMPONENT_TYPE_UINT:
+ if( PixelFormatAttribs.ComponentSize == 1 )
+ *((Uint8*)pDstCmp) = (Uint8) std::min( std::max(fCurrCmpCol*255,0.f), 255.f );
+ else if( PixelFormatAttribs.ComponentSize == 2 )
+ *((Uint16*)pDstCmp) = (Uint16) std::min( std::max(fCurrCmpCol*255,0.f), 255.f );
+ else
+ assert(false);
+ break;
+
+ default: assert("Unsupport component type" && false);
+ }
+ }
+ }
+ CurrLevelOffset += Stride * MipHeight;
+ }
+ for(Uint32 Level = 0; Level < TexDesc.MipLevels; ++Level)
+ {
+ SubResouces[Level].pData = Data.data() + LevelDataOffsets[Level];
+ }
+}
+
+
+void TestTexturing::Init( IRenderDevice *pDevice, IDeviceContext *pDeviceContext, TEXTURE_FORMAT TexFormat, bool bUseOpenGL, float fMinXCoord, float fMinYCoord, float fXExtent, float fYExtent )
+{
+ m_pRenderDevice = pDevice;
+ m_TextureFormat = TexFormat;
+ m_pDeviceContext = pDeviceContext;
+
+ 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);
+
+ ShaderCreationAttribs CreationAttrs;
+ BasicShaderSourceStreamFactory BasicSSSFactory;
+ CreationAttrs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ CreationAttrs.Desc.TargetProfile = bUseOpenGL ? SHADER_PROFILE_GL_4_2 : SHADER_PROFILE_DX_5_0;
+
+ RefCntAutoPtr<Diligent::IShader> pVS, pPS;
+ {
+ CreationAttrs.FilePath = bUseOpenGL ? "Shaders\\TextureTestGL.vsh" : "Shaders\\TextureTestDX.vsh";
+ CreationAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX;
+ m_pRenderDevice->CreateShader( CreationAttrs, &pVS );
+ }
+
+ bool bIsIntTexture = PixelFormatAttribs.ComponentType == COMPONENT_TYPE_UINT ||
+ PixelFormatAttribs.ComponentType == COMPONENT_TYPE_SINT;
+ {
+ if( bIsIntTexture )
+ CreationAttrs.FilePath = bUseOpenGL ? "Shaders\\TextureIntTestGL.psh" : "Shaders\\TextureIntTestDX.psh";
+ else
+ CreationAttrs.FilePath = bUseOpenGL ? "Shaders\\TextureTestGL.psh" : "Shaders\\TextureTestDX.psh";
+ CreationAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL;
+
+ 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.TextureName = "g_tex2DTest";
+ CreationAttrs.Desc.NumStaticSamplers = 1;
+ CreationAttrs.Desc.StaticSamplers = &StaticSampler;
+ 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<Uint8> Data;
+ std::vector<TextureSubResData> 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<ITextureView> pDefaultSRV;
+ TextureViewDesc ViewDesc;
+ ViewDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE;
+ 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] = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ PSODesc.GraphicsPipeline.NumRenderTargets = 1;
+ PSODesc.GraphicsPipeline.pVS = pVS;
+ PSODesc.GraphicsPipeline.pPS = pPS;
+
+ 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 );
+ pDevice->CreatePipelineState(PSODesc, &m_pPSO);
+
+ pVS->BindResources(m_pResourceMapping, 0);
+ pPS->BindResources(m_pResourceMapping, 0);
+}
+
+void TestTexturing::Draw()
+{
+ m_pDeviceContext->SetPipelineState(m_pPSO);
+ m_pDeviceContext->TransitionShaderResources(m_pPSO, nullptr);
+ m_pDeviceContext->CommitShaderResources(nullptr, 0);
+
+ IBuffer *pBuffs[] = {m_pVertexBuff};
+ Uint32 Strides[] = {sizeof(float)*5};
+ Uint32 Offsets[] = {0};
+ m_pDeviceContext->SetVertexBuffers( 0, 1, pBuffs, Strides, Offsets, SET_VERTEX_BUFFERS_FLAG_RESET );
+
+ Diligent::DrawAttribs DrawAttrs;
+ DrawAttrs.Topology = Diligent::PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+ DrawAttrs.NumVertices = 4; // Draw quad
+ m_pDeviceContext->Draw( DrawAttrs );
+}