diff options
Diffstat (limited to 'RenderScript/src/PSODescParser.cpp')
| -rw-r--r-- | RenderScript/src/PSODescParser.cpp | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/RenderScript/src/PSODescParser.cpp b/RenderScript/src/PSODescParser.cpp new file mode 100644 index 0000000..9f00f95 --- /dev/null +++ b/RenderScript/src/PSODescParser.cpp @@ -0,0 +1,257 @@ +/* Copyright 2015-2016 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. + */ + +#include "pch.h" +#include "PSODescParser.h" +#include "BlendStateDescParser.h" +#include "RasterizerStateDescParser.h" +#include "DepthStencilStateDescParser.h" +#include "InputLayoutDescParser.h" + +namespace std +{ + DEFINE_ENUM_HASH( Diligent::PRIMITIVE_TOPOLOGY_TYPE ) +} + +namespace Diligent +{ + class RTVFormatsParser; + + template<> + class MemberBinder<RTVFormatsParser> : public MemberBinderBase + { + public: + MemberBinder( size_t /*MemberOffset*/, size_t /*Dummy*/ ) : + // We will use a pointer to the GraphicsPipelineDesc structure itself + MemberBinderBase( 0 ), + m_TexFmtLoader(0, "RTVFormats", m_TexFmtEnumMapping) + { + } + + virtual void GetValue( lua_State *L, const void* pBasePointer )override + { + const auto &GraphicsPipeline = GetMemberByOffest< GraphicsPipelineDesc >(pBasePointer, m_MemberOffset); + PushLuaArray( L, GraphicsPipeline.RTVFormats, GraphicsPipeline.RTVFormats + GraphicsPipeline.NumRenderTargets, [&]( const TEXTURE_FORMAT &Fmt ) + { + m_TexFmtLoader.GetValue(L, &Fmt); + }); + } + + virtual void SetValue( lua_State *L, int Index, void* pBasePointer )override + { + auto &GraphicsPipeline = GetMemberByOffest< GraphicsPipelineDesc >( pBasePointer, m_MemberOffset ); + if(lua_type(L,Index) == LUA_TTABLE) + { + ParseLuaArray( L, Index, pBasePointer, [&]( void* _pBasePointer, int StackIndex, int NewArrayIndex ) + { + // Lua array indices are 1-based + NewArrayIndex -= 1; + VERIFY( pBasePointer == _pBasePointer, "Sanity check failed" ); + if( NewArrayIndex < 0 || NewArrayIndex >= MaxRenderTargets ) + SCRIPT_PARSING_ERROR( L, "Render target array index ", NewArrayIndex," is out of allowed range [", 0, ' ', MaxRenderTargets-1, ']' ); + + m_TexFmtLoader.SetValue(L, StackIndex, &GraphicsPipeline.RTVFormats[NewArrayIndex]); + GraphicsPipeline.NumRenderTargets = std::max(GraphicsPipeline.NumRenderTargets, static_cast<Uint32>(NewArrayIndex+1)); + } + ); + } + else if(lua_type(L,Index) == LUA_TSTRING) + { + m_TexFmtLoader.SetValue(L, Index, &GraphicsPipeline.RTVFormats[0]); + GraphicsPipeline.NumRenderTargets = 1; + } + else + { + SCRIPT_PARSING_ERROR( L, "Unexpected type ", lua_typename(L, Index), ". Table of strings or a string are expected" ); + } + } + private: + TextureFormatEnumMapping m_TexFmtEnumMapping; + EnumMemberBinder<TEXTURE_FORMAT> m_TexFmtLoader; + }; + + + template<> + class MemberBinder<SampleDesc> : public MemberBinderBase + { + public: + MemberBinder( size_t MemberOffset, size_t Dummy ) : + MemberBinderBase( MemberOffset ) + { + DEFINE_BINDER( m_Bindings, SampleDesc, Count, Uint32, Validator<Uint32>("Count", 1,32) ); + DEFINE_BINDER( m_Bindings, SampleDesc, Quality, Uint32, Validator<Uint32>("Quality", 0,std::numeric_limits<Uint32>::max()) ); + } + + virtual void GetValue( lua_State *L, const void* pBasePointer )override + { + const auto &SmplDesc = GetMemberByOffest< SampleDesc >(pBasePointer, m_MemberOffset); + PushLuaTable(L, &SmplDesc, m_Bindings); + } + + virtual void SetValue( lua_State *L, int Index, void* pBasePointer )override + { + auto &SmplDesc = GetMemberByOffest< SampleDesc >( pBasePointer, m_MemberOffset ); + ParseLuaTable( L, Index, &SmplDesc, m_Bindings ); + } + + private: + BindingsMapType m_Bindings; + }; + + template<> + class MemberBinder<GraphicsPipelineDesc> : public MemberBinderBase + { + public: + MemberBinder( size_t MemberOffset, size_t Dummy ) : + MemberBinderBase( MemberOffset ) + { + std::vector<String> AllowedMetatable = { "Metatables.Shader" }; + + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, pVS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, pPS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, pDS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, pHS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, pGS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + + //D3D12_STREAM_OUTPUT_DESC StreamOutput; + + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, BlendDesc, BlendStateDesc, 0 ) + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, SampleMask, Uint32, Validator<Uint32>() ) + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, RasterizerDesc, RasterizerStateDesc, 0 ) + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, DepthStencilDesc, DepthStencilStateDesc, 0 ) + + auto *pLayoutElemBinder = + new MemberBinder<InputLayoutDesc>( + offsetof(GraphicsPipelineDesc, InputLayout), + offsetof(PSODescParser::PSODescWrapper, LayoutElementsBuffer) - offsetof(PSODescParser::PSODescWrapper, GraphicsPipeline) + ); + m_Bindings.insert( std::make_pair( "InputLayout", std::unique_ptr<MemberBinderBase>(pLayoutElemBinder) ) ); + + //D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; + + DEFINE_ENUM_ELEMENT_MAPPING( m_PrimTopologyTypeEnumMapping, PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED ); + DEFINE_ENUM_ELEMENT_MAPPING( m_PrimTopologyTypeEnumMapping, PRIMITIVE_TOPOLOGY_TYPE_POINT ); + DEFINE_ENUM_ELEMENT_MAPPING( m_PrimTopologyTypeEnumMapping, PRIMITIVE_TOPOLOGY_TYPE_LINE ); + DEFINE_ENUM_ELEMENT_MAPPING( m_PrimTopologyTypeEnumMapping, PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE ); + DEFINE_ENUM_ELEMENT_MAPPING( m_PrimTopologyTypeEnumMapping, PRIMITIVE_TOPOLOGY_TYPE_PATCH ); + VERIFY( m_PrimTopologyTypeEnumMapping.m_Str2ValMap.size() == PRIMITIVE_TOPOLOGY_TYPE_NUM_TYPES, + "Unexpected map size. Did you update PRIMITIVE_TOPOLOGY_TYPE enum?" ); + VERIFY( m_PrimTopologyTypeEnumMapping.m_Val2StrMap.size() == PRIMITIVE_TOPOLOGY_TYPE_NUM_TYPES, + "Unexpected map size. Did you update PRIMITIVE_TOPOLOGY_TYPE enum?" ); + DEFINE_ENUM_BINDER( m_Bindings, GraphicsPipelineDesc, PrimitiveTopologyType, PRIMITIVE_TOPOLOGY_TYPE, m_PrimTopologyTypeEnumMapping ); + + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, RTVFormats, RTVFormatsParser, 0 ); + DEFINE_ENUM_BINDER( m_Bindings, GraphicsPipelineDesc, DSVFormat, TEXTURE_FORMAT, m_TexFmtEnumMapping ); + + DEFINE_BINDER( m_Bindings, GraphicsPipelineDesc, SmplDesc, SampleDesc, 0 ); + + //Uint32 NodeMask; + } + + virtual void GetValue( lua_State *L, const void* pBasePointer )override + { + const auto &GraphicsPipeline = GetMemberByOffest< GraphicsPipelineDesc >(pBasePointer, m_MemberOffset); + PushLuaTable(L, &GraphicsPipeline, m_Bindings); + } + + virtual void SetValue( lua_State *L, int Index, void* pBasePointer )override + { + auto &GraphicsPipeline = GetMemberByOffest< GraphicsPipelineDesc >( pBasePointer, m_MemberOffset ); + ParseLuaTable( L, Index, &GraphicsPipeline, m_Bindings ); + } + private: + TextureFormatEnumMapping m_TexFmtEnumMapping; + EnumMapping < PRIMITIVE_TOPOLOGY_TYPE > m_PrimTopologyTypeEnumMapping; + BindingsMapType m_Bindings; + }; + + + template<> + class MemberBinder<ComputePipelineDesc> : public MemberBinderBase + { + public: + MemberBinder( size_t MemberOffset, size_t Dummy ) : + MemberBinderBase( MemberOffset ) + { + std::vector<String> AllowedMetatable = { "Metatables.Shader" }; + DEFINE_BINDER( m_Bindings, ComputePipelineDesc, pCS, EngineObjectPtrLoader<IShader>, AllowedMetatable ); + } + + virtual void GetValue( lua_State *L, const void* pBasePointer )override + { + const auto &ComputePipeline = GetMemberByOffest< ComputePipelineDesc >(pBasePointer, m_MemberOffset); + PushLuaTable(L, &ComputePipeline, m_Bindings); + } + + virtual void SetValue( lua_State *L, int Index, void* pBasePointer )override + { + auto &ComputePipeline = GetMemberByOffest< ComputePipelineDesc >( pBasePointer, m_MemberOffset ); + ParseLuaTable( L, Index, &ComputePipeline, m_Bindings ); + } + private: + BindingsMapType m_Bindings; + }; + + + const Char* PSODescParser::PSODescLibName = "PipelineState"; + PSODescParser::PSODescParser( IRenderDevice *pRenderDevice, lua_State *L ) : + EngineObjectParserCommon<IPipelineState>( pRenderDevice, L, PSODescLibName ), + m_SetPSOBinding( this, L, "Context", "SetPipelineState", &PSODescParser::SetPSO ) + { + DEFINE_BUFFERED_STRING_BINDER( m_Bindings, PSODescWrapper, Name, NameBuffer ) + + DEFINE_BINDER( m_Bindings, PSODescWrapper, IsComputePipeline, Bool, Validator<Bool>() ) + DEFINE_BINDER( m_Bindings, PSODescWrapper, SRBAllocationGranularity, Uint32, Validator<Uint32>("SRBAllocationGranularity", 1, 65536) ) + + DEFINE_BINDER( m_Bindings, PSODescWrapper, GraphicsPipeline, GraphicsPipelineDesc, 0 ) + DEFINE_BINDER( m_Bindings, PSODescWrapper, ComputePipeline, ComputePipelineDesc, 0 ) + }; + + void PSODescParser::CreateObj( lua_State *L ) + { + INIT_LUA_STACK_TRACKING( L ); + + PSODescWrapper PSODesc; + ParseLuaTable( L, 1, &PSODesc, m_Bindings ); + + CHECK_LUA_STACK_HEIGHT(); + + auto ppPSO = reinterpret_cast<IPipelineState**>(lua_newuserdata( L, sizeof( IPipelineState* ) )); + *ppPSO = nullptr; + m_pRenderDevice->CreatePipelineState( PSODesc, ppPSO ); + if( *ppPSO == nullptr ) + SCRIPT_PARSING_ERROR( L, "Failed to create Pipeline State Object state object" ) + + CHECK_LUA_STACK_HEIGHT( +1 ); + } + + int PSODescParser::SetPSO( lua_State *L ) + { + auto *pPSO = *GetUserData<IPipelineState**>( L, 1, m_MetatableRegistryName.c_str() ); + + auto *pContext = LoadDeviceContextFromRegistry( L ); + pContext->SetPipelineState( pPSO ); + + return 0; + } +} |
