void ShaderManager::CreateInputLayout(ID3DBlob* VS, ID3D11InputLayout* &inputLayout) { HRESULT hr; std::vector<D3D11_INPUT_ELEMENT_DESC> inputElementDescArray; ID3D11ShaderReflection* pReflection; hr = D3DReflect(VS->GetBufferPointer(), VS->GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &pReflection); assert(hr == S_OK); D3D11_SHADER_DESC shaderDesc; pReflection->GetDesc(&shaderDesc); unsigned int i = 0; for (; i < shaderDesc.InputParameters; ++i) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; pReflection->GetInputParameterDesc(i, ¶mDesc); D3D11_INPUT_ELEMENT_DESC inputElementDesc; inputElementDesc.SemanticName = paramDesc.SemanticName; inputElementDesc.SemanticIndex = paramDesc.SemanticIndex; if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) inputElementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) inputElementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) inputElementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) inputElementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) inputElementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } inputElementDesc.InputSlot = 0; inputElementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; inputElementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputElementDesc.InstanceDataStepRate = 0; inputElementDescArray.push_back(inputElementDesc); } // Initialize input layout hr = D3D11Renderer::GetInstance()->m_pD3D11Device->CreateInputLayout(&inputElementDescArray[0], i, VS->GetBufferPointer(), VS->GetBufferSize(), &inputLayout); assert(hr == S_OK); pReflection->Release(); }
//----------------------------------------------------------------------------- bool CPUTShaderDX11::ShaderRequiresPerModelPayload( CPUTConfigBlock &properties ) { ID3D11ShaderReflection *pReflector = NULL; D3DReflect( mpBlob->GetBufferPointer(), mpBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pReflector); // Walk through the shader input bind descriptors. // If any of them begin with '@', then we need a unique material per model (i.e., we need to clone the material). int ii=0; D3D11_SHADER_INPUT_BIND_DESC desc; HRESULT hr = pReflector->GetResourceBindingDesc( ii++, &desc ); while( SUCCEEDED(hr) ) { cString tagName = s2ws(desc.Name); CPUTConfigEntry *pValue = properties.GetValueByName(tagName); if( !pValue->IsValid() ) { // We didn't find our property in the file. Is it in the global config block? pValue = CPUTMaterial::mGlobalProperties.GetValueByName(tagName); } cString boundName = pValue->ValueAsString(); if( (boundName.length() > 0) && ((boundName[0] == '@') || (boundName[0] == '#')) ) { return true; } hr = pReflector->GetResourceBindingDesc( ii++, &desc ); } return false; }
bool ReloadShader( char * szShaderCode, int nShaderCodeSize, char * szErrorBuffer, int nErrorBufferSize ) { ID3DBlob * pCode = NULL; ID3DBlob * pErrors = NULL; if (D3DCompile( szShaderCode, nShaderCodeSize, NULL, NULL, NULL, "main", "ps_4_0", NULL, NULL, &pCode, &pErrors ) != S_OK) { memset( szErrorBuffer, 0, nErrorBufferSize ); strncpy( szErrorBuffer, (char*)pErrors->GetBufferPointer(), nErrorBufferSize - 1 ); return false; } if (theShader) { theShader->Release(); theShader = NULL; } if (pDevice->CreatePixelShader( pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &theShader ) != S_OK) { return false; } D3DReflect( pCode->GetBufferPointer(), pCode->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pShaderReflection ); pCBuf = pShaderReflection->GetConstantBufferByIndex(0); return true; }
HRESULT PixelShaderDynamic::InitShaderReflection(const void* pShaderBytecode, SIZE_T unBytecodeLength) { if(m_pReflector) { m_pReflector->Release(); m_pReflector = nullptr; } HRESULT retVal = S_OK; retVal = D3DReflect(pShaderBytecode, unBytecodeLength, IID_ID3D11ShaderReflection, (void**)&m_pReflector); if(FAILED(retVal)) { MessageBox(NULL, L"Failed To Create Pixel Shader Reflection (Dynamic Linked PS)" , L"", MB_OK | MB_ICONERROR); return retVal; } UINT unNumInterfaces = m_pReflector->GetNumInterfaceSlots(); m_vInterfaceNames.resize(unNumInterfaces); m_pDynamicLinkageArray = (ID3D11ClassInstance**)calloc(unNumInterfaces, sizeof(ID3D11ClassInstance*)); if(!m_pDynamicLinkageArray) { MessageBox(NULL, L"Not Enough Memory to Allocate Dynamic Linkage Array (Pixel Shader)" , L"", MB_OK | MB_ICONERROR); return E_FAIL; } return S_OK; }
HRESULT ShaderBase::processLoadedShaderBlob( ID3DBlob *shaderSource ) { HRESULT res = build( shaderSource ); if ( FAILED(res) ) { std::cout << "Error (ShaderBase::processLoadedShaderBlob): Error creating shader" << std::endl; return res; } // setup buffers using the shader reflection ID3D11ShaderReflection *reflector; res = D3DReflect( shaderSource->GetBufferPointer(), shaderSource->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&reflector ); if ( FAILED( res ) ) { std::cout << "Error (ShaderBase::processLoadedShaderBlob): Error creating shader reflection" << std::endl; return res; } D3D11_SHADER_DESC shaderDesc; ZeroMemory( &shaderDesc, sizeof( D3D11_SHADER_DESC ) ); res = reflector->GetDesc( &shaderDesc ); if ( FAILED( res ) ) { std::cout << "Error (ShaderBase::processLoadedShaderBlob): Error creating shader reflection description" << std::endl; reflector->Release(); return res; } for ( UINT i = 0U; i < shaderDesc.ConstantBuffers; ++i ) { ID3D11ShaderReflectionConstantBuffer *constBuffReflection = reflector->GetConstantBufferByIndex( i ); D3D11_SHADER_BUFFER_DESC shaderBuffDesc; constBuffReflection->GetDesc( &shaderBuffDesc ); //TODO: these can be put on the stack ConstantBuffer *cBuff = new ConstantBuffer( m_dxDev, i, shaderBuffDesc.Name ); cBuff->create( shaderBuffDesc.Size ); for ( UINT j = 0U; j < shaderBuffDesc.Variables; ++j ) { ID3D11ShaderReflectionVariable *variableRefl = constBuffReflection->GetVariableByIndex( j ); D3D11_SHADER_VARIABLE_DESC shaderVarDesc; variableRefl->GetDesc( &shaderVarDesc ); cBuff->addVariableDefinition( shaderVarDesc.Name, shaderVarDesc.StartOffset, shaderVarDesc.Size ); } m_constBuffers.push_back( cBuff ); m_dxConstBuffers.push_back( cBuff->getDxBufferPtr() ); } reflector->Release(); return S_OK; }
std::shared_ptr<GraphicsPipelineState> Device::createGraphicsPipelineState(const GraphicsPipelineStateParams& params) { ID3D11VertexShader* vertexShader = nullptr; if (SUCCEEDED(m_device->CreateVertexShader(params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, nullptr, &vertexShader))) { ID3D11ShaderReflection* vertexShaderReflector = nullptr; if (SUCCEEDED(D3DReflect(params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, IID_ID3D11ShaderReflection, (void**)&vertexShaderReflector))) { ID3D11PixelShader* pixelShader = nullptr; if (SUCCEEDED(m_device->CreatePixelShader(params.m_psParams.m_shaderBytecode, params.m_psParams.m_bytecodeLength, nullptr, &pixelShader))) { ID3D11ShaderReflection* pixelShaderReflector = nullptr; if (SUCCEEDED(D3DReflect(params.m_psParams.m_shaderBytecode, params.m_psParams.m_bytecodeLength, IID_ID3D11ShaderReflection, (void**)&pixelShaderReflector))) { CD3D11_DEPTH_STENCIL_DESC depthStencilDesc(D3D11_DEFAULT); depthStencilDesc.DepthEnable = params.m_depthStencilParams.m_depthEnable; ID3D11DepthStencilState* depthStencilState = nullptr; if (SUCCEEDED(m_device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState))) { D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; ID3D11InputLayout* inputLayout = nullptr; if (SUCCEEDED(m_device->CreateInputLayout(layout, ARRAYSIZE(layout), params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, &inputLayout))) { return std::make_shared<GraphicsPipelineState>(vertexShader, vertexShaderReflector, pixelShader, pixelShaderReflector, depthStencilState, params.m_stencilRef, inputLayout, params.m_primitiveTopologyType); } depthStencilState->Release(); } pixelShaderReflector->Release(); } pixelShader->Release(); } vertexShaderReflector->Release(); } vertexShader->Release(); } return nullptr; }
void PixelShader::InitFromFile(std::string inFileName) { assert(FileUtil::FileExists(inFileName.c_str())); CleanUp(); DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; std::wstring filename = std::wstring(inFileName.begin(), inFileName.end()); #ifdef _DEBUG dwShaderFlags |= D3DCOMPILE_DEBUG; dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* pPSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "PS", "ps_5_0", dwShaderFlags, 0, &pPSBlob, &pErrorBlob)); if (pErrorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } ID3D11ShaderReflection* pPixelShaderReflection = NULL; D3DCall(D3DReflect(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pPixelShaderReflection)); D3D11_SHADER_DESC shader_desc; pPixelShaderReflection->GetDesc(&shader_desc); for (int i = 0; i < shader_desc.BoundResources; i++) { D3D11_SHADER_INPUT_BIND_DESC resource_desc; pPixelShaderReflection->GetResourceBindingDesc(i, &resource_desc); // FETCH RESOURCES switch (resource_desc.Type) { case D3D_SHADER_INPUT_TYPE::D3D_SIT_TEXTURE: mTextures[resource_desc.Name] = resource_desc.BindPoint; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_SAMPLER: mSamplers[resource_desc.Name] = resource_desc.BindPoint; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_CBUFFER: mConstantBuffers[resource_desc.Name] = resource_desc.BindPoint; break; default: break; } } D3DCall(theRenderContext.GetDevice()->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &mHandle)); pPSBlob->Release(); }
static void dx11_fill_constant_table(ShaderConstantTable& out_constants, ShaderConstantTable& out_samplers, const ShaderCode& bytecode) { out_constants.clear(); out_samplers.clear(); ID3D11ShaderReflection* refl = NULL; D3DReflect( bytecode.data(), bytecode.size(), IID_ID3D11ShaderReflection, (void**)&refl); if( refl ) { HRESULT hr = S_OK; D3D11_SHADER_DESC refl_desc; hr = refl->GetDesc(&refl_desc); for( uint32 i=0; i<refl_desc.ConstantBuffers; ++i ) { ID3D11ShaderReflectionConstantBuffer* cb = refl->GetConstantBufferByIndex(i); D3D11_SHADER_BUFFER_DESC sb_desc; cb->GetDesc(&sb_desc); for( uint32 j=0; j<sb_desc.Variables; ++j ) { ID3D11ShaderReflectionVariable* var = cb->GetVariableByIndex(j); D3D11_SHADER_VARIABLE_DESC var_desc; var->GetDesc(&var_desc); ShaderConstantDescr scd; scd.name = var_desc.Name; scd.register_index = var_desc.StartOffset/16; scd.register_count = var_desc.Size/16; out_constants.push_back(scd); } } for( uint32 i=0; i<refl_desc.BoundResources; ++i ) { D3D11_SHADER_INPUT_BIND_DESC desc; refl->GetResourceBindingDesc(i, &desc); if( desc.Type == D3D10_SIT_SAMPLER ) { ShaderConstantDescr scd; scd.name = desc.Name; scd.register_index = desc.BindPoint; scd.register_count = desc.BindCount; } } refl->Release(); } }
//must called after shader compiled HRESULT initializeShaderReflector() { HRESULT hr = E_FAIL; hr = D3DReflect(pShaderContextBuffer->GetBufferPointer(), pShaderContextBuffer->GetBufferSize(), IID_ID3D11ShaderReflection, reinterpret_cast<void**>(&pShaderReflector)); if (FAILED(hr)) { return hr; } return S_OK; }
void ComputeShader::ShaderConstants::Enumerate( ID3DBlob& _ShaderBlob ) { ID3D11ShaderReflection* pReflector = NULL; D3DReflect( _ShaderBlob.GetBufferPointer(), _ShaderBlob.GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &pReflector ); D3D11_SHADER_DESC ShaderDesc; pReflector->GetDesc( &ShaderDesc ); // Enumerate bound resources for ( int ResourceIndex=0; ResourceIndex < int(ShaderDesc.BoundResources); ResourceIndex++ ) { D3D11_SHADER_INPUT_BIND_DESC BindDesc; pReflector->GetResourceBindingDesc( ResourceIndex, &BindDesc ); BindingDesc** ppDesc = NULL; switch ( BindDesc.Type ) { case D3D_SIT_TEXTURE: ppDesc = &m_TextureName2Descriptor.Add( BindDesc.Name ); break; case D3D_SIT_CBUFFER: ppDesc = &m_ConstantBufferName2Descriptor.Add( BindDesc.Name ); break; case D3D_SIT_STRUCTURED: ppDesc = &m_StructuredBufferName2Descriptor.Add( BindDesc.Name ); break; case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: ppDesc = &m_UAVName2Descriptor.Add( BindDesc.Name ); break; } if ( ppDesc == NULL ) continue; // We're not interested in that type ! *ppDesc = new BindingDesc(); (*ppDesc)->SetName( BindDesc.Name ); (*ppDesc)->Slot = BindDesc.BindPoint; #ifdef __DEBUG_UPLOAD_ONLY_ONCE (*ppDesc)->bUploaded = false; // Not uploaded yet ! #endif } pReflector->Release(); }
void FSlateD3DPS::Create( const FString& Filename, const FString& EntryPoint, const FString& ShaderModel ) { TRefCountPtr<ID3DBlob> Blob; CompileShader( Filename, EntryPoint, ShaderModel, Blob); HRESULT Hr = GD3DDevice->CreatePixelShader( Blob->GetBufferPointer(), Blob->GetBufferSize(), NULL, PixelShader.GetInitReference() ); check( SUCCEEDED(Hr) ); TRefCountPtr<ID3D11ShaderReflection> Reflector; Hr = D3DReflect( Blob->GetBufferPointer(), Blob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)Reflector.GetInitReference() ); check( SUCCEEDED(Hr) ); GetShaderBindings( Reflector, ShaderBindings ); }
void Shader::SetReflections(const ShaderBlobs& blobs) { for(unsigned type = EShaderStage::VS; type < EShaderStage::COUNT; ++type) { if (blobs.of[type]) { void** ppBuffer = reinterpret_cast<void**>(&this->mReflections.of[type]); if (FAILED(D3DReflect(blobs.of[type]->GetBufferPointer(), blobs.of[type]->GetBufferSize(), IID_ID3D11ShaderReflection, ppBuffer))) { Log::Error("Cannot get vertex shader reflection"); assert(false); } } } }
void FSlateD3DVS::Create( const FString& Filename, const FString& EntryPoint, const FString& ShaderModel, D3D11_INPUT_ELEMENT_DESC* VertexLayout, uint32 VertexLayoutCount ) { TRefCountPtr<ID3DBlob> Blob; CompileShader( Filename, EntryPoint, ShaderModel, Blob); HRESULT Hr = GD3DDevice->CreateVertexShader( Blob->GetBufferPointer(), Blob->GetBufferSize(), NULL, VertexShader.GetInitReference() ); check( SUCCEEDED(Hr) ); Hr = GD3DDevice->CreateInputLayout( VertexLayout, VertexLayoutCount, Blob->GetBufferPointer(), Blob->GetBufferSize(), InputLayout.GetInitReference() ); check( SUCCEEDED(Hr) ); TRefCountPtr<ID3D11ShaderReflection> Reflector; Hr = D3DReflect( Blob->GetBufferPointer(), Blob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)Reflector.GetInitReference() ); check( SUCCEEDED(Hr) ); GetShaderBindings( Reflector, ShaderBindings ); }
void D3D12Shader::ReflectShaderByteCode(ShaderReflectionDescriptor& reflectionDesc) const { HRESULT hr = 0; /* Get shader reflection */ ComPtr<ID3D12ShaderReflection> reflection; hr = D3DReflect(byteCode_.data(), byteCode_.size(), IID_PPV_ARGS(reflection.ReleaseAndGetAddressOf())); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader reflection"); D3D12_SHADER_DESC shaderDesc; hr = reflection->GetDesc(&shaderDesc); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader descriptor"); /* Get input parameter descriptors */ if (GetType() == ShaderType::Vertex) ReflectShaderVertexAttributes(reflection.Get(), shaderDesc, reflectionDesc); /* Get input bindings */ ReflectShaderInputBindings(reflection.Get(), shaderDesc, GetStageFlags(), reflectionDesc); }
void ShaderBase::InitUniforms(void* s, size_t size) { ID3D11ShaderReflection* ref = NULL; D3DReflect(s, size, IID_ID3D11ShaderReflection, (void**) &ref); ID3D11ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0); D3D11_SHADER_BUFFER_DESC bufd; if (FAILED(buf->GetDesc(&bufd))) { UniformsSize = 0; if (UniformData) { OVR_FREE(UniformData); UniformData = 0; } return; } for(unsigned i = 0; i < bufd.Variables; i++) { ID3D11ShaderReflectionVariable* var = buf->GetVariableByIndex(i); if (var) { D3D11_SHADER_VARIABLE_DESC vd; if (SUCCEEDED(var->GetDesc(&vd))) { Uniform u; u.Name = vd.Name; u.Offset = vd.StartOffset; u.Size = vd.Size; UniformInfo.PushBack(u); } } } UniformsSize = bufd.Size; UniformData = (unsigned char*)OVR_ALLOC(bufd.Size); }
// -------------------------------------------------------- // Creates the DirectX Geometry shader and sets it up for // stream output, if possible. // // shaderBlob - The shader's compiled code // // Returns true if shader is created correctly, false otherwise // -------------------------------------------------------- bool SimpleGeometryShader::CreateShaderWithStreamOut(ID3DBlob* shaderBlob) { // Clean up first, in the event this method is // called more than once on the same object this->CleanUp(); // Reflect shader info ID3D11ShaderReflection* refl; D3DReflect( shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&refl); // Get shader info D3D11_SHADER_DESC shaderDesc; refl->GetDesc(&shaderDesc); // Set up the output signature streamOutVertexSize = 0; std::vector<D3D11_SO_DECLARATION_ENTRY> soDecl; for (unsigned int i = 0; i < shaderDesc.OutputParameters; i++) { // Get the info about this entry D3D11_SIGNATURE_PARAMETER_DESC paramDesc; refl->GetOutputParameterDesc(i, ¶mDesc); // Create the SO Declaration D3D11_SO_DECLARATION_ENTRY entry; entry.SemanticIndex = paramDesc.SemanticIndex; entry.SemanticName = paramDesc.SemanticName; entry.Stream = paramDesc.Stream; entry.StartComponent = 0; // Assume starting at 0 entry.OutputSlot = 0; // Assume the first output slot // Check the mask to determine how many components are used entry.ComponentCount = CalcComponentCount(paramDesc.Mask); // Increment the size streamOutVertexSize += entry.ComponentCount * sizeof(float); // Add to the declaration soDecl.push_back(entry); } // Rasterization allowed? unsigned int rast = allowStreamOutRasterization ? 0 : D3D11_SO_NO_RASTERIZED_STREAM; // Create the shader HRESULT result = device->CreateGeometryShaderWithStreamOutput( shaderBlob->GetBufferPointer(), // Shader blob pointer shaderBlob->GetBufferSize(), // Shader blob size &soDecl[0], // Stream out declaration soDecl.size(), // Number of declaration entries NULL, // Buffer strides (not used - assume tightly packed?) 0, // No buffer strides rast, // Index of the stream to rasterize (if any) NULL, // Not using class linkage &shader); return (result == S_OK); }
// -------------------------------------------------------- // Loads the specified shader and builds the variable table using shader // reflection. This must be a separate step from the constructor since // we can't invoke derived class overrides in the base class constructor. // // shaderFile - A "wide string" specifying the compiled shader to load // // Returns true if shader is loaded properly, false otherwise // -------------------------------------------------------- bool ISimpleShader::LoadShaderFile(LPCWSTR shaderFile) { // Load the shader to a blob and ensure it worked ID3DBlob* shaderBlob = 0; HRESULT hr = D3DReadFileToBlob(shaderFile, &shaderBlob); if (hr != S_OK) { return false; } // Create the shader - Calls an overloaded version of this abstract // method in the appropriate child class shaderValid = CreateShader(shaderBlob); if (!shaderValid) { shaderBlob->Release(); return false; } // Set up shader reflection to get information about // this shader and its variables, buffers, etc. ID3D11ShaderReflection* refl; D3DReflect( shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&refl); // Get the description of the shader D3D11_SHADER_DESC shaderDesc; refl->GetDesc(&shaderDesc); // Create an array of constant buffers constantBufferCount = shaderDesc.ConstantBuffers; constantBuffers = new SimpleConstantBuffer[constantBufferCount]; // Handle bound resources (like shaders and samplers) unsigned int resourceCount = shaderDesc.BoundResources; for (unsigned int r = 0; r < resourceCount; r++) { // Get this resource's description D3D11_SHADER_INPUT_BIND_DESC resourceDesc; refl->GetResourceBindingDesc(r, &resourceDesc); // Check the type switch (resourceDesc.Type) { case D3D_SIT_TEXTURE: // A texture resource textureTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint)); break; case D3D_SIT_SAMPLER: // A sampler resource samplerTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint)); break; } } // Loop through all constant buffers for (unsigned int b = 0; b < constantBufferCount; b++) { // Get this buffer ID3D11ShaderReflectionConstantBuffer* cb = refl->GetConstantBufferByIndex(b); // Get the description of this buffer D3D11_SHADER_BUFFER_DESC bufferDesc; cb->GetDesc(&bufferDesc); // Get the description of the resource binding, so // we know exactly how it's bound in the shader D3D11_SHADER_INPUT_BIND_DESC bindDesc; refl->GetResourceBindingDescByName(bufferDesc.Name, &bindDesc); // Set up the buffer and put its pointer in the table constantBuffers[b].BindIndex = bindDesc.BindPoint; cbTable.insert(std::pair<std::string, SimpleConstantBuffer*>(bufferDesc.Name, &constantBuffers[b])); // Create this constant buffer D3D11_BUFFER_DESC newBuffDesc; newBuffDesc.Usage = D3D11_USAGE_DEFAULT; newBuffDesc.ByteWidth = bufferDesc.Size; newBuffDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; newBuffDesc.CPUAccessFlags = 0; newBuffDesc.MiscFlags = 0; newBuffDesc.StructureByteStride = 0; device->CreateBuffer(&newBuffDesc, 0, &constantBuffers[b].ConstantBuffer); // Set up the data buffer for this constant buffer constantBuffers[b].LocalDataBuffer = new unsigned char[bufferDesc.Size]; ZeroMemory(constantBuffers[b].LocalDataBuffer, bufferDesc.Size); // Loop through all variables in this buffer for (unsigned int v = 0; v < bufferDesc.Variables; v++) { // Get this variable ID3D11ShaderReflectionVariable* var = cb->GetVariableByIndex(v); // Get the description of the variable D3D11_SHADER_VARIABLE_DESC varDesc; var->GetDesc(&varDesc); // Create the variable struct SimpleShaderVariable varStruct; varStruct.ConstantBufferIndex = b; varStruct.ByteOffset = varDesc.StartOffset; varStruct.Size = varDesc.Size; // Get a string version std::string varName(varDesc.Name); // Add this variable to the table varTable.insert(std::pair<std::string, SimpleShaderVariable>(varName, varStruct)); } } // All set refl->Release(); shaderBlob->Release(); return true; }
// -------------------------------------------------------- // Creates the DirectX vertex shader // // shaderBlob - The shader's compiled code // // Returns true if shader is created correctly, false otherwise // -------------------------------------------------------- bool SimpleVertexShader::CreateShader(ID3DBlob* shaderBlob) { // Clean up first, in the event this method is // called more than once on the same object this->CleanUp(); // Create the shader from the blob HRESULT result = device->CreateVertexShader( shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), 0, &shader); // Did the creation work? if (result != S_OK) return false; // Vertex shader was created successfully, so we now use the // shader code to re-reflect and create an input layout that // matches what the vertex shader expects. Code adapted from: // https://takinginitiative.wordpress.com/2011/12/11/directx-1011-basic-shader-reflection-automatic-input-layout-creation/ // Reflect shader info ID3D11ShaderReflection* refl; D3DReflect( shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&refl); // Get shader info D3D11_SHADER_DESC shaderDesc; refl->GetDesc(&shaderDesc); // Read input layout description from shader info std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc; for (unsigned int i = 0; i< shaderDesc.InputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; refl->GetInputParameterDesc(i, ¶mDesc); // Fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // Determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } // Save element desc inputLayoutDesc.push_back(elementDesc); } // Try to create Input Layout HRESULT hr = device->CreateInputLayout( &inputLayoutDesc[0], inputLayoutDesc.size(), shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), &inputLayout); // All done, clean up refl->Release(); return true; }
bool DXShader::VInitFromFile(File* file) { if (!this->VInitShader(file)) return false; if (!m_shaderReflection) { //Reflect shader info D3DReflect(m_shaderBlob->GetBufferPointer(), m_shaderBlob->GetBufferSize(), __uuidof(ID3D11ShaderReflection), reinterpret_cast<void**>(&m_shaderReflection)); } //Get description of the shader D3D11_SHADER_DESC shaderDesc; m_shaderReflection->GetDesc(&shaderDesc); //Create array of constant buffers m_cbCount = shaderDesc.ConstantBuffers; m_cbArray = new ConstantBuffer[m_cbCount]; //Handle bound resources (shaders or samples) size_t resourceCnt = shaderDesc.BoundResources; for (size_t i = 0; i < resourceCnt; i++) { //Get the resource description D3D11_SHADER_INPUT_BIND_DESC resourceDesc; m_shaderReflection->GetResourceBindingDesc(i, &resourceDesc); //Check what type switch (resourceDesc.Type) { case D3D_SIT_TEXTURE: m_texTable.insert(std::pair<std::string, size_t>(resourceDesc.Name, resourceDesc.BindPoint)); break; case D3D_SIT_SAMPLER: m_sampTable.insert(std::pair<std::string, size_t>(resourceDesc.Name, resourceDesc.BindPoint)); break; case D3D_SIT_STRUCTURED: m_texTable.insert(std::pair<std::string, size_t>(resourceDesc.Name, resourceDesc.BindPoint)); break; } } //Loop over all constant buffers for (size_t i = 0; i < m_cbCount; i++) { //Get this buffer ID3D11ShaderReflectionConstantBuffer* cb = m_shaderReflection->GetConstantBufferByIndex(i); //Get description of buffer D3D11_SHADER_BUFFER_DESC bufferDesc; cb->GetDesc(&bufferDesc); //Get the description of the resource binding //so we know how its bound to shader D3D11_SHADER_INPUT_BIND_DESC bindDesc; m_shaderReflection->GetResourceBindingDescByName(bufferDesc.Name, &bindDesc); //set up buffer and put its pointer into the table m_cbArray[i].BindIndex = bindDesc.BindPoint; m_cbTable.insert(std::pair<std::string, ConstantBuffer*>(bufferDesc.Name, &m_cbArray[i])); //Create this constant buffer D3D11_BUFFER_DESC _newBufferDesc; _newBufferDesc.Usage = D3D11_USAGE_DEFAULT; _newBufferDesc.ByteWidth = bufferDesc.Size; _newBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; _newBufferDesc.CPUAccessFlags = 0; _newBufferDesc.MiscFlags = 0; _newBufferDesc.StructureByteStride = 0; m_device->CreateBuffer(&_newBufferDesc, 0, &m_cbArray[i].Buffer); //setup the data buffer for the cb m_cbArray[i].LocalDataBuffer = new BYTE[bufferDesc.Size]; ZeroMemory(m_cbArray[i].LocalDataBuffer, bufferDesc.Size); //Iterate over all variables in this buffer for (size_t v = 0; v < bufferDesc.Variables; v++) { //Get this variables ID3D11ShaderReflectionVariable* var = cb->GetVariableByIndex(v); //Get variable description D3D11_SHADER_VARIABLE_DESC varDesc; var->GetDesc(&varDesc); //Create the variable struct ShaderVariable variable; variable.ConstantBufferIndex = i; variable.ByteOffset = varDesc.StartOffset; variable.Size = varDesc.Size; //Get a string representation std::string varName = varDesc.Name; //Add variable to table m_svTable.insert(std::pair<std::string, ShaderVariable>(varName, variable)); } } //ReleaseCOM(m_shaderReflection); //ReleaseCOM(m_shaderBlob); return true; }
AGN::ShaderDX11::ShaderDX11(DeviceDX11& a_deviceReference, const uint16_t a_aId, EShaderType a_type, ID3D11DeviceChild* a_shaderHandle, ID3DBlob* a_shaderBlob) : m_deviceReference(a_deviceReference) , m_aId(a_aId) , m_type(a_type) , m_shaderHandle(a_shaderHandle) , m_shaderBlob(a_shaderBlob) , m_shaderReflection(nullptr) , m_shaderReflectionDesc(nullptr) { HRESULT hr = D3DReflect(m_shaderBlob->GetBufferPointer(), m_shaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&m_shaderReflection); if (FAILED(hr)) g_log.error("Failed performing reflection on shader"); m_shaderReflectionDesc = new D3D11_SHADER_DESC(); // TODO: refactor, we dont want pointers just to be able to fwd declare :/ memset(m_shaderReflectionDesc, 0, sizeof(D3D11_SHADER_DESC)); hr = m_shaderReflection->GetDesc(m_shaderReflectionDesc); if (FAILED(hr)) g_log.error("Failed getting reflection desc on shader"); int numConstantBuffers; D3D11_SHADER_BUFFER_DESC* constantBufferDescriptions; // reflect on constant buffers getConstantBufferDesc(constantBufferDescriptions, numConstantBuffers); if (numConstantBuffers > 0) { m_constantBuffers.reserve(numConstantBuffers); m_bufferHandles.reserve(numConstantBuffers); // create constant buffers for (uint16_t i = 0; i < numConstantBuffers; i++) { ConstantBufferDX11* constantBuffer = new ConstantBufferDX11(); D3D11_SHADER_BUFFER_DESC bufferDescription; memcpy(&bufferDescription, &constantBufferDescriptions[i], sizeof(D3D11_SHADER_BUFFER_DESC)); // TODO: refactor :/ // Get name memcpy(constantBuffer->name, bufferDescription.Name, sizeof(char) * strlen(bufferDescription.Name)); // Get Size constantBuffer->size = bufferDescription.Size; // Create CPU-side buffer constantBuffer->buffer = new uint8_t[constantBuffer->size]; memset(constantBuffer->buffer, 0, constantBuffer->size); // Get bind point for (uint16_t k = 0; k < m_shaderReflectionDesc->BoundResources; ++k) { D3D11_SHADER_INPUT_BIND_DESC ibdesc; memset(&ibdesc, 0, sizeof(D3D11_SHADER_INPUT_BIND_DESC)); hr = m_shaderReflection->GetResourceBindingDesc(k, &ibdesc); if (FAILED(hr)) g_log.error("Failed getting reflection D3D11_SHADER_INPUT_BIND_DESC on shader"); if (strcmp(ibdesc.Name, constantBufferDescriptions[i].Name) == 0) { constantBuffer->bindpoint = ibdesc.BindPoint; break; } } if (constantBuffer->bindpoint == -1) { g_log.error("Did not find bindpoint for Constant buffer with the name %s", constantBufferDescriptions[i].Name); assert(false); } // get reflection for buffer variables ID3D11ShaderReflectionConstantBuffer* bufferReflection = m_shaderReflection->GetConstantBufferByName(bufferDescription.Name); constantBuffer->propertyList.reserve(bufferDescription.Variables); // get all variables in buffer for (unsigned j = 0; j < bufferDescription.Variables; ++j) { ConstantBufferPropertyDX11* constantBufferProperty = new ConstantBufferPropertyDX11(); memset(constantBufferProperty, 0, sizeof(ConstantBufferPropertyDX11)); // get variable description D3D11_SHADER_VARIABLE_DESC variableDesc; memset(&variableDesc, 0, sizeof(D3D11_SHADER_VARIABLE_DESC)); bufferReflection->GetVariableByIndex(j)->GetDesc(&variableDesc); memcpy(constantBufferProperty->name, variableDesc.Name, sizeof(char) * strlen(variableDesc.Name)); constantBufferProperty->offset = variableDesc.StartOffset; constantBufferProperty->size = variableDesc.Size; constantBuffer->propertyList.push_back(constantBufferProperty); } // create handle to actual buffer D3D11_BUFFER_DESC newConstantBufferDesc; memset(&newConstantBufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); newConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; newConstantBufferDesc.ByteWidth = constantBufferDescriptions[i].Size; newConstantBufferDesc.CPUAccessFlags = 0; newConstantBufferDesc.Usage = D3D11_USAGE_DEFAULT; newConstantBufferDesc.MiscFlags = 0; newConstantBufferDesc.StructureByteStride = 0; // TODO: think if this is the correct location for this function, in essence, we are doing the devices job in this constructor? HRESULT hr = a_deviceReference.getD3D11Device()->CreateBuffer(&newConstantBufferDesc, nullptr, &constantBuffer->d3dhandle); m_bufferHandles.push_back(constantBuffer->d3dhandle); if (FAILED(hr)) { g_log.error("failure creating constant buffer"); return; } m_constantBuffers.push_back(constantBuffer); } } delete[] constantBufferDescriptions; #ifdef AGN_DEBUG //AGN::logHResultData(hr); #endif // AGN_DEBUG }
// The following code below is from: // https://takinginitiative.wordpress.com/2011/12/11/directx-1011-basic-shader-reflection-automatic-input-layout-creation/ // I wrapped the code with ComPtr's to ensure no leaks occur. // This creates the input layout associated with a vertex shader at runtime // through shader reflection. bool Ivy::Graphics::DXShader::CreateVertexInputLayout() const { // Reflect shader info ComPtr<ID3D11ShaderReflection> l_pVertexShaderReflection; HRESULT hr = D3DReflect(m_pVertexShaderBlob->GetBufferPointer(), m_pVertexShaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, reinterpret_cast<void**>(l_pVertexShaderReflection.GetAddressOf())); if(FAILED(hr)) return false; // Get shader info D3D11_SHADER_DESC shaderDesc; l_pVertexShaderReflection->GetDesc(&shaderDesc); // Read input layout description from shader info std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc; for (unsigned int i = 0; i < shaderDesc.InputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; l_pVertexShaderReflection->GetInputParameterDesc(i, ¶mDesc); // Fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; elementDesc.AlignedByteOffset = (i == 0) ? 0 : D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // Determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } // Save element desc inputLayoutDesc.push_back(elementDesc); } // Try to create Input Layout hr = device->GetID3D11Device()->CreateInputLayout(inputLayoutDesc.data(), static_cast<unsigned>(inputLayoutDesc.size()), m_pVertexShaderBlob->GetBufferPointer(), m_pVertexShaderBlob->GetBufferSize(), const_cast<ID3D11InputLayout**>(m_pInputLayout.GetAddressOf())); if (FAILED(hr)) return false; std::cout << "Input Layout was created successfully..." << std::endl; return true; }
/// 生成する bool D3DShader::Create(DXGIManager *pDxgi) { if(m_pVsh)return true; auto pDevice=pDxgi->GetD3DDevice(); // vertex shader { Microsoft::WRL::ComPtr<ID3DBlob> vblob; HRESULT hr = CompileShaderFromFile(m_info.path, m_info.vs , vblob.GetAddressOf()); if (FAILED(hr)) return false; hr = pDevice->CreateVertexShader( vblob->GetBufferPointer(), vblob->GetBufferSize() , NULL, m_pVsh.ReleaseAndGetAddressOf()); if (FAILED(hr)) return false; // vertex shader reflection Microsoft::WRL::ComPtr<ID3D11ShaderReflection> pReflector; hr = D3DReflect(vblob->GetBufferPointer(), vblob->GetBufferSize() , IID_ID3D11ShaderReflection, &pReflector); if (FAILED(hr)) return false; D3D11_SHADER_DESC shaderdesc; pReflector->GetDesc(&shaderdesc); // Create InputLayout std::vector<D3D11_INPUT_ELEMENT_DESC> vbElement; for (size_t i = 0; i < shaderdesc.InputParameters; ++i){ D3D11_SIGNATURE_PARAMETER_DESC sigdesc; pReflector->GetInputParameterDesc(i, &sigdesc); auto format = GetDxgiFormat(sigdesc.ComponentType, sigdesc.Mask); D3D11_INPUT_ELEMENT_DESC eledesc = { sigdesc.SemanticName , sigdesc.SemanticIndex , format , 0 // 決め打ち , D3D11_APPEND_ALIGNED_ELEMENT // 決め打ち , D3D11_INPUT_PER_VERTEX_DATA // 決め打ち , 0 // 決め打ち }; vbElement.push_back(eledesc); } if (!vbElement.empty()){ hr = pDevice->CreateInputLayout(&vbElement[0], vbElement.size(), vblob->GetBufferPointer(), vblob->GetBufferSize(), &m_pInputLayout); if (FAILED(hr)) return false; } } // pixel shader { Microsoft::WRL::ComPtr<ID3DBlob> pblob; auto hr = CompileShaderFromFile(m_info.path, m_info.ps , pblob.GetAddressOf()); if (FAILED(hr)) return false; hr = pDevice->CreatePixelShader( pblob->GetBufferPointer(), pblob->GetBufferSize() , NULL, m_pPsh.ReleaseAndGetAddressOf()); if (FAILED(hr)) return false; } return true; }
//Since we're precompiling the shaders, we dont need all the extra parameters //Assume this is a function within the renderer thus we have access to private render members Shader* CreateShader( const std::string& name, const std::string& vsFile, const std::string& psFile, const std::string& gsFile = "") { Shader newShader = new Shader(name); ID3D11ShaderReflection *vsReflect(nullptr); ID3D11ShaderReflection *psReflect(nullptr); ID3D11ShaderReflection *gsReflect(nullptr); if(!vsFile.empty()) { auto vsFileRes = new WhaleFile(vsFile); if(!vsFileRes) { log_sxerror("Shader", "Error opening VS file %s. Cannot continue", vsFile.c_str()); delete newShader; return nullptr; } auto vsFilePtr = vsFileRes->GetMem(); HRESULT result = device->CreateVertexShader(vsFilePtr, vsFileRes.Size(), NULL, &newShader->vertexShader); if(FAILED(result)) { log_sxerror("Shader", "Could not create Vertex shader from %s. Cannot continue!", vsFile.c_str()); //Clean up after ourselves before returning delete vsFileRes; delete newShader; return nullptr; } //Grab the input signature from the vertex shader result = D3DGetInputSignatureBlob(vsFilePtr, vsFileRes.Size(), &newShader->inputSignature); if(FAILED(result)) { log_sxerror("Shader", "Could not get Input signature from %s. Cannot continue!", vsFile.c_str()); delete vsFileRes; delete newShader; return nullptr; } result = D3DReflect(vsFilePtr, vsFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&vsReflect); if(FAILED(result)) { log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", vsFile.c_str()); delete vsFileRes; delete newShader; return nullptr; } delete vsFileRes; } if(!psFile.empty()) { auto psFileRes = new WhaleFile(psFile); if(!psFileRes) { log_sxerror("Shader", "Error opening PS file %s. Cannot continue!", psFile.c_str()); delete newShader; SAFE_RELEASE(vsReflect); return nullptr; } auto psFilePtr = psFileRes->GetMem(); HRESULT result = device->CreatePixelShader(psFilePtr, psFileRes.Size(), NULL, &newShader->pixelShader); if(FAILED(result)) { log_sxerror("Shader", "Could not create Pixel shader from %s. Cannot continue!", psFile.c_str()); delete psFileRes; SAFE_RELEASE(vsReflect); delete newShader; return nullptr; } result = D3DReflect(psFilePtr, psFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&psReflect); if(FAILED(result)) { log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", psFile.c_str()); delete psFileRes; SAFE_RELEASE(vsReflect); delete newShader; return nullptr; } delete psFileRes; } if(!gsFile.empty()) { auto gsFileRes = new WhaleFile(gsFile); if(!gsFileRes) { log_sxerror("Shader", "Error opening PS file %s. Cannot continue!", gsFile.c_str()); delete newShader; SAFE_RELEASE(vsReflect); return nullptr; } auto gsFilePtr = gsFileRes->GetMem(); HRESULT result = device->CreatePixelShader(gsFilePtr, gsFileRes.Size(), NULL, &newShader->geometryShader); if(FAILED(result)) { log_sxerror("Shader", "Could not create Pixel shader from %s. Cannot continue!", gsFile.c_str()); delete gsFileRes; SAFE_RELEASE(vsReflect); SAFE_RELEASE(psReflect); delete newShader; return nullptr; } result = D3DReflect(gsFilePtr, gsFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&gsReflect); if(FAILED(result)) { log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", gsFile.c_str()); delete gsFileRes; SAFE_RELEASE(psReflect); SAFE_RELEASE(vsReflect); delete newShader; return nullptr; } delete gsFileRes; } bool res = GenerateShaderConstants(newShader, vsReflect, psReflect, gsReflect); if(!res) { log_sxerror("Shader", "Error Generating shader constants for shader %s.", name.c_str()); SAFE_RELEASE(vsReflect); SAFE_RELEASE(psReflect); SAFE_RELEASE(gsReflect); delete newShader; return nullptr; } res = GenerateShaderSamplers(newShader, vsReflect, psReflect, gsReflect); if(!res) { log_sxerror("Shader", "Error Generating shader samplers for shader %s.", name.c_str()); SAFE_RELEASE(vsReflect); SAFE_RELEASE(psReflect); SAFE_RELEASE(gsReflect); delete newShader; return nullptr; } res = ValidateShader(newShader, vsReflect, psReflect, gsReflect); if(!res) { log_sxerror("Shader", "Error validating shader %s", name.c_str()); delete newShader; newShader = nullptr; } SAFE_RELEASE(vsReflect); SAFE_RELEASE(psReflect); SAFE_RELEASE(gsReflect); return newShader; }
void VertexShader::InitFromFile(std::string inFileName) { assert(FileUtil::FileExists(inFileName.c_str())); CleanUp(); DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; std::wstring filename = std::wstring(inFileName.begin(), inFileName.end()); #ifdef _DEBUG // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. dwShaderFlags |= D3DCOMPILE_DEBUG; // Disable optimizations to further improve shader debugging dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* pVSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", dwShaderFlags, 0, &pVSBlob, &pErrorBlob)); if (pErrorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } D3DCall(theRenderContext.GetDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &mHandle)); // Reflect shader info ID3D11ShaderReflection* pVertexShaderReflection = NULL; D3DCall(D3DReflect(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pVertexShaderReflection)); // Get shader info D3D11_SHADER_DESC shaderDesc; pVertexShaderReflection->GetDesc(&shaderDesc); // Read input layout description from shader info std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc; for (int i = 0; i < shaderDesc.InputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; pVertexShaderReflection->GetInputParameterDesc(i, ¶mDesc); // fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; if (i == 0) elementDesc.AlignedByteOffset = 0; else elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } //save element desc inputLayoutDesc.push_back(elementDesc); } // Try to create Input Layout D3DCall(theRenderContext.GetDevice()->CreateInputLayout(&inputLayoutDesc[0], inputLayoutDesc.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &mVertexLayout)); //Free allocation shader reflection memory pVertexShaderReflection->Release(); pVSBlob->Release(); }
void ShaderInfo::ReflectShader(ID3D10Blob* shader) { D3D11_SHADER_DESC sd; D3DReflect(shader->GetBufferPointer(), shader->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&m_reflector); m_reflector->GetDesc(&sd); shaderDesc = sd; for(UINT i = 0; i < sd.InputParameters; i++) { //Mask gives info on how many components D3D11_SIGNATURE_PARAMETER_DESC inputparam_desc; m_reflector->GetInputParameterDesc(i, &inputparam_desc); m_inputParams.push_back(inputparam_desc); } for(UINT i = 0; i < sd.OutputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC outputparam_desc; m_reflector->GetOutputParameterDesc(i, &outputparam_desc); m_outputParams.push_back(outputparam_desc); } for(UINT i = 0; i < sd.BoundResources; i++) { D3D11_SHADER_INPUT_BIND_DESC resource_desc; //Bind point is the register location m_reflector->GetResourceBindingDesc(i, &resource_desc); if(resource_desc.Type == D3D_SIT_CBUFFER) { Cbuffer* cbuffer = new Cbuffer(); cbuffer->input_bind_desc = resource_desc; ID3D11ShaderReflectionConstantBuffer* cb = m_reflector->GetConstantBufferByName(cbuffer->input_bind_desc.Name); cb->GetDesc(&cbuffer->buffer_desc); for(UINT j = 0; j < cbuffer->buffer_desc.Variables; j++) { Variable* var = new Variable(); ID3D11ShaderReflectionVariable* variable = cb->GetVariableByIndex(j); variable->GetDesc(&var->var); ID3D11ShaderReflectionType* type = variable->GetType(); type->GetDesc(&var->type); cbuffer->vars.push_back(var); //register cbuff vars with ShaderVars object // switch(var->type.Class) { // case D3D_SVC_MATRIX_COLUMNS: // if(var->type.Rows == 4 && var->type.Columns == 4) { // cbp->AddMatrix(var->var.Name); // } // else if(var->type.Rows == 3 && var->type.Columns == 3) { // // } // break; // case D3D_SVC_VECTOR: // if(var->type.Columns == 4) { // cbp->AddVector(var->var.Name); // } // else if(var->type.Columns == 3) { // // } // else if(var->type.Columns == 2) { // // } // break; // case D3D_SVC_SCALAR: // if(var->type.Type == D3D_SVT_FLOAT) { // cbp->AddScalar(var->var.Name); // } // break; // default: // break; // } } m_cbuffers.push_back(cbuffer); } else if(resource_desc.Type == D3D_SIT_SAMPLER) { m_samplers.push_back(resource_desc); } else if(resource_desc.Type == D3D_SIT_TEXTURE) { m_textures.push_back(resource_desc); } else { m_resources.push_back(resource_desc); } } }
//----------------------------------------------------------------------------- void CPUTMaterialDX11::ReadShaderSamplersAndTextures( ID3DBlob *pBlob, CPUTShaderParameters *pShaderParameter ) { // *************************** // Use shader reflection to get texture and sampler names. We use them later to bind .mtl texture-specification to shader parameters/variables. // TODO: Currently do this only for PS. Do for other shader types too. // TODO: Generalize, so easy to call for different shader types // *************************** ID3D11ShaderReflection *pReflector = NULL; D3D11_SHADER_INPUT_BIND_DESC desc; D3DReflect( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pReflector); // Walk through the shader input bind descriptors. Find the samplers and textures. int ii=0; HRESULT hr = pReflector->GetResourceBindingDesc( ii++, &desc ); while( SUCCEEDED(hr) ) { switch( desc.Type ) { case D3D_SIT_TEXTURE: pShaderParameter->mTextureParameterCount++; break; case D3D_SIT_SAMPLER: pShaderParameter->mSamplerParameterCount++; break; case D3D_SIT_CBUFFER: pShaderParameter->mConstantBufferParameterCount++; break; case D3D_SIT_TBUFFER: case D3D_SIT_STRUCTURED: case D3D_SIT_BYTEADDRESS: pShaderParameter->mBufferParameterCount++; break; case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: pShaderParameter->mUAVParameterCount++; break; } hr = pReflector->GetResourceBindingDesc( ii++, &desc ); } pShaderParameter->mpTextureParameterName = new cString[pShaderParameter->mTextureParameterCount]; pShaderParameter->mpTextureParameterBindPoint = new UINT[ pShaderParameter->mTextureParameterCount]; pShaderParameter->mpSamplerParameterName = new cString[pShaderParameter->mSamplerParameterCount]; pShaderParameter->mpSamplerParameterBindPoint = new UINT[ pShaderParameter->mSamplerParameterCount]; pShaderParameter->mpBufferParameterName = new cString[pShaderParameter->mBufferParameterCount]; pShaderParameter->mpBufferParameterBindPoint = new UINT[ pShaderParameter->mBufferParameterCount]; pShaderParameter->mpUAVParameterName = new cString[pShaderParameter->mUAVParameterCount]; pShaderParameter->mpUAVParameterBindPoint = new UINT[ pShaderParameter->mUAVParameterCount]; pShaderParameter->mpConstantBufferParameterName = new cString[pShaderParameter->mConstantBufferParameterCount]; pShaderParameter->mpConstantBufferParameterBindPoint = new UINT[ pShaderParameter->mConstantBufferParameterCount]; // Start over. This time, copy the names. ii=0; UINT textureIndex = 0; UINT samplerIndex = 0; UINT bufferIndex = 0; UINT uavIndex = 0; UINT constantBufferIndex = 0; hr = pReflector->GetResourceBindingDesc( ii++, &desc ); while( SUCCEEDED(hr) ) { switch( desc.Type ) { case D3D_SIT_TEXTURE: pShaderParameter->mpTextureParameterName[textureIndex] = s2ws(desc.Name); pShaderParameter->mpTextureParameterBindPoint[textureIndex] = desc.BindPoint; textureIndex++; break; case D3D_SIT_SAMPLER: pShaderParameter->mpSamplerParameterName[samplerIndex] = s2ws(desc.Name); pShaderParameter->mpSamplerParameterBindPoint[samplerIndex] = desc.BindPoint; samplerIndex++; break; case D3D_SIT_CBUFFER: pShaderParameter->mpConstantBufferParameterName[constantBufferIndex] = s2ws(desc.Name); pShaderParameter->mpConstantBufferParameterBindPoint[constantBufferIndex] = desc.BindPoint; constantBufferIndex++; break; case D3D_SIT_TBUFFER: case D3D_SIT_STRUCTURED: case D3D_SIT_BYTEADDRESS: pShaderParameter->mpBufferParameterName[bufferIndex] = s2ws(desc.Name); pShaderParameter->mpBufferParameterBindPoint[bufferIndex] = desc.BindPoint; bufferIndex++; break; case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: pShaderParameter->mpUAVParameterName[uavIndex] = s2ws(desc.Name); pShaderParameter->mpUAVParameterBindPoint[uavIndex] = desc.BindPoint; uavIndex++; break; } hr = pReflector->GetResourceBindingDesc( ii++, &desc ); } }
void ShaderCompiler::getShaderResources(ID3DBlob* blob, std::weak_ptr<DX12DeviceContext> context) { // use reflection to extract bind info ID3D12ShaderReflection* reflect = nullptr; D3D12_SHADER_DESC progDesc; D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&reflect)); reflect->GetDesc(&progDesc); parseConstantBuffers(reflect, progDesc, context); // shader resources (textures and buffers) bound for (uint_fast32_t i = 0; i < progDesc.BoundResources; ++i) { D3D12_SHADER_INPUT_BIND_DESC resdesc; auto res = reflect->GetResourceBindingDesc(i, &resdesc); switch (resdesc.Type) { case D3D_SHADER_INPUT_TYPE::D3D_SIT_BYTEADDRESS: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_BYTEADDRESS"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_CBUFFER: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_CBUFFER"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_SAMPLER: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_SAMPLER"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_STRUCTURED: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_STRUCTURED"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_TBUFFER: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_TBUFFER"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_TEXTURE: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_TEXTURE"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_APPEND_STRUCTURED: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_APPEND_STRUCTURED"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_CONSUME_STRUCTURED: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_CONSUME_STRUCTURED"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_RWBYTEADDRESS: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_RWBYTEADDRESS"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_RWSTRUCTURED: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_RWSTRUCTURED"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_RWTYPED: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_RWTYPED"; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: LOGS << "Resource binding : " << resdesc.Name << ", D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER"; break; default: throw new std::runtime_error("Unknown D3D_SHADER_INPUT_TYPE"); break; } } }
bool D3D11ComputeEvaluator::Compile(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, ID3D11DeviceContext *deviceContext) { if (srcDesc.length > dstDesc.length) { Far::Error(Far::FAR_RUNTIME_ERROR, "srcDesc length must be less than or equal to " "dstDesc length.\n"); return false; } DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined(D3D10_SHADER_RESOURCES_MAY_ALIAS) dwShaderFlags |= D3D10_SHADER_RESOURCES_MAY_ALIAS; #endif #ifdef _DEBUG dwShaderFlags |= D3DCOMPILE_DEBUG; #endif std::ostringstream ss; ss << srcDesc.length; std::string lengthValue(ss.str()); ss.str(""); ss << srcDesc.stride; std::string srcStrideValue(ss.str()); ss.str(""); ss << dstDesc.stride; std::string dstStrideValue(ss.str()); ss.str(""); ss << _workGroupSize; std::string workgroupSizeValue(ss.str()); ss.str(""); D3D_SHADER_MACRO defines[] = { "LENGTH", lengthValue.c_str(), "SRC_STRIDE", srcStrideValue.c_str(), "DST_STRIDE", dstStrideValue.c_str(), "WORK_GROUP_SIZE", workgroupSizeValue.c_str(), 0, 0 }; ID3DBlob * computeShaderBuffer = NULL; ID3DBlob * errorBuffer = NULL; HRESULT hr = D3DCompile(shaderSource, strlen(shaderSource), NULL, &defines[0], NULL, "cs_main", "cs_5_0", dwShaderFlags, 0, &computeShaderBuffer, &errorBuffer); if (FAILED(hr)) { if (errorBuffer != NULL) { Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling HLSL shader: %s\n", (CHAR*)errorBuffer->GetBufferPointer()); errorBuffer->Release(); return false; } } ID3D11Device *device = NULL; deviceContext->GetDevice(&device); assert(device); device->CreateClassLinkage(&_classLinkage); assert(_classLinkage); device->CreateComputeShader(computeShaderBuffer->GetBufferPointer(), computeShaderBuffer->GetBufferSize(), _classLinkage, &_computeShader); assert(_computeShader); ID3D11ShaderReflection *reflector; D3DReflect(computeShaderBuffer->GetBufferPointer(), computeShaderBuffer->GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &reflector); assert(reflector); assert(reflector->GetNumInterfaceSlots() == 1); reflector->Release(); computeShaderBuffer->Release(); _classLinkage->GetClassInstance("singleBufferCompute", 0, &_singleBufferKernel); assert(_singleBufferKernel); _classLinkage->GetClassInstance("separateBufferCompute", 0, &_separateBufferKernel); assert(_separateBufferKernel); D3D11_BUFFER_DESC cbDesc; ZeroMemory(&cbDesc, sizeof(cbDesc)); cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbDesc.MiscFlags = 0; cbDesc.ByteWidth = sizeof(KernelUniformArgs); device->CreateBuffer(&cbDesc, NULL, &_uniformArgs); return true; }
bool Shader::createShaders(const Microsoft::WRL::ComPtr<ID3D11Device> &pDevice , const std::wstring &shaderFile, const std::string &vsFunc, const std::string &psFunc) { // vertex shader { Microsoft::WRL::ComPtr<ID3DBlob> vblob; HRESULT hr = CompileShaderFromFile(shaderFile.c_str(), vsFunc.c_str(), "vs_4_0_level_9_1", &vblob); if (FAILED(hr)) return false; hr = pDevice->CreateVertexShader(vblob->GetBufferPointer(), vblob->GetBufferSize(), NULL, &m_pVsh); if (FAILED(hr)) return false; // vertex shader reflection Microsoft::WRL::ComPtr<ID3D11ShaderReflection> pReflector; hr = D3DReflect(vblob->GetBufferPointer(), vblob->GetBufferSize(), IID_ID3D11ShaderReflection, &pReflector); if (FAILED(hr)) return false; OutputDebugPrintfA("#### VertexShader ####\n"); if (!m_constant->Initialize(pDevice, SHADERSTAGE_VERTEX, pReflector)){ return false; } D3D11_SHADER_DESC shaderdesc; pReflector->GetDesc(&shaderdesc); // Create InputLayout std::vector<D3D11_INPUT_ELEMENT_DESC> vbElement; for (size_t i = 0; i < shaderdesc.InputParameters; ++i){ D3D11_SIGNATURE_PARAMETER_DESC sigdesc; pReflector->GetInputParameterDesc(i, &sigdesc); auto format = GetDxgiFormat(sigdesc.ComponentType, sigdesc.Mask); D3D11_INPUT_ELEMENT_DESC eledesc = { sigdesc.SemanticName , sigdesc.SemanticIndex , format , 0 // 決め打ち , D3D11_APPEND_ALIGNED_ELEMENT // 決め打ち , D3D11_INPUT_PER_VERTEX_DATA // 決め打ち , 0 // 決め打ち }; vbElement.push_back(eledesc); } if (!vbElement.empty()){ hr = pDevice->CreateInputLayout(&vbElement[0], vbElement.size(), vblob->GetBufferPointer(), vblob->GetBufferSize(), &m_pInputLayout); if (FAILED(hr)) return false; } } // pixel shader { Microsoft::WRL::ComPtr<ID3DBlob> pblob; auto hr = CompileShaderFromFile(shaderFile.c_str(), psFunc.c_str(), "ps_4_0_level_9_1", &pblob); if (FAILED(hr)) return false; hr = pDevice->CreatePixelShader(pblob->GetBufferPointer(), pblob->GetBufferSize(), NULL, &m_pPsh); if (FAILED(hr)) return false; // pixel shader reflection Microsoft::WRL::ComPtr<ID3D11ShaderReflection> pReflector; hr = D3DReflect(pblob->GetBufferPointer(), pblob->GetBufferSize(), IID_ID3D11ShaderReflection, &pReflector); if (FAILED(hr)) return false; OutputDebugPrintfA("#### PixelShader ####\n"); if (!m_constant->Initialize(pDevice, SHADERSTAGE_PIXEL, pReflector)){ return false; } } return true; }
bool compileHLSLShaderDx11(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer) { BX_TRACE("DX11"); const char* profile = _cmdLine.findOption('p', "profile"); if (NULL == profile) { fprintf(stderr, "Shader profile must be specified.\n"); return false; } bool debug = _cmdLine.hasArg('\0', "debug"); uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; flags |= debug ? D3DCOMPILE_DEBUG : 0; flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0; flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0; flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0; bool werror = _cmdLine.hasArg('\0', "Werror"); if (werror) { flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS; } uint32_t optimization = 3; if (_cmdLine.hasArg(optimization, 'O') ) { optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelDx11)-1); flags |= s_optimizationLevelDx11[optimization]; } else { flags |= D3DCOMPILE_SKIP_OPTIMIZATION; } BX_TRACE("Profile: %s", profile); BX_TRACE("Flags: 0x%08x", flags); ID3DBlob* code; ID3DBlob* errorMsg; // Output preprocessed shader so that HLSL can be debugged via GPA // or PIX. Compiling through memory won't embed preprocessed shader // file path. std::string hlslfp; if (debug) { hlslfp = _cmdLine.findOption('o'); hlslfp += ".hlsl"; writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() ); } HRESULT hr = D3DCompile(_code.c_str() , _code.size() , hlslfp.c_str() , NULL , NULL , "main" , profile , flags , 0 , &code , &errorMsg ); if (FAILED(hr) || (werror && NULL != errorMsg) ) { const char* log = (char*)errorMsg->GetBufferPointer(); int32_t line = 0; int32_t column = 0; int32_t start = 0; int32_t end = INT32_MAX; if (2 == sscanf(log, "(%u,%u):", &line, &column) && 0 != line) { start = bx::uint32_imax(1, line-10); end = start + 20; } printCode(_code.c_str(), line, start, end); fprintf(stderr, "Error: 0x%08x %s\n", (uint32_t)hr, log); errorMsg->Release(); return false; } UniformArray uniforms; ID3D11ShaderReflection* reflect = NULL; hr = D3DReflect(code->GetBufferPointer() , code->GetBufferSize() , IID_ID3D11ShaderReflection , (void**)&reflect ); if (FAILED(hr) ) { fprintf(stderr, "Error: 0x%08x\n", (uint32_t)hr); return false; } D3D11_SHADER_DESC desc; hr = reflect->GetDesc(&desc); if (FAILED(hr) ) { fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", (uint32_t)hr); return false; } BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version); BX_TRACE("Num constant buffers: %d", desc.ConstantBuffers); BX_TRACE("Input:"); uint8_t numAttrs = 0; uint16_t attrs[bgfx::Attrib::Count]; if (profile[0] == 'v') // Only care about input semantic on vertex shaders { for (uint32_t ii = 0; ii < desc.InputParameters; ++ii) { D3D11_SIGNATURE_PARAMETER_DESC spd; reflect->GetInputParameterDesc(ii, &spd); BX_TRACE("\t%2d: %s%d, vt %d, ct %d, mask %x, reg %d" , ii , spd.SemanticName , spd.SemanticIndex , spd.SystemValueType , spd.ComponentType , spd.Mask , spd.Register ); const RemapInputSemantic& ris = findInputSemantic(spd.SemanticName, spd.SemanticIndex); if (ris.m_attr != bgfx::Attrib::Count) { attrs[numAttrs] = bgfx::attribToId(ris.m_attr); ++numAttrs; } } } BX_TRACE("Output:"); for (uint32_t ii = 0; ii < desc.OutputParameters; ++ii) { D3D11_SIGNATURE_PARAMETER_DESC spd; reflect->GetOutputParameterDesc(ii, &spd); BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType); } uint16_t size = 0; for (uint32_t ii = 0; ii < bx::uint32_min(1, desc.ConstantBuffers); ++ii) { ID3D11ShaderReflectionConstantBuffer* cbuffer = reflect->GetConstantBufferByIndex(ii); D3D11_SHADER_BUFFER_DESC bufferDesc; hr = cbuffer->GetDesc(&bufferDesc); size = (uint16_t)bufferDesc.Size; if (SUCCEEDED(hr) ) { BX_TRACE("%s, %d, vars %d, size %d" , bufferDesc.Name , bufferDesc.Type , bufferDesc.Variables , bufferDesc.Size ); for (uint32_t jj = 0; jj < bufferDesc.Variables; ++jj) { ID3D11ShaderReflectionVariable* var = cbuffer->GetVariableByIndex(jj); ID3D11ShaderReflectionType* type = var->GetType(); D3D11_SHADER_VARIABLE_DESC varDesc; hr = var->GetDesc(&varDesc); if (SUCCEEDED(hr) ) { D3D11_SHADER_TYPE_DESC constDesc; hr = type->GetDesc(&constDesc); if (SUCCEEDED(hr) ) { UniformType::Enum uniformType = findUniformTypeDx11(constDesc); if (UniformType::Count != uniformType && 0 != (varDesc.uFlags & D3D_SVF_USED) ) { Uniform un; un.name = varDesc.Name; un.type = uniformType; un.num = constDesc.Elements; un.regIndex = varDesc.StartOffset; un.regCount = BX_ALIGN_16(varDesc.Size)/16; uniforms.push_back(un); BX_TRACE("\t%s, %d, size %d, flags 0x%08x, %d" , varDesc.Name , varDesc.StartOffset , varDesc.Size , varDesc.uFlags , uniformType ); } else { BX_TRACE("\t%s, unknown type", varDesc.Name); } } } } } } BX_TRACE("Bound:"); for (uint32_t ii = 0; ii < desc.BoundResources; ++ii) { D3D11_SHADER_INPUT_BIND_DESC bindDesc; hr = reflect->GetResourceBindingDesc(ii, &bindDesc); if (SUCCEEDED(hr) ) { // if (bindDesc.Type == D3D_SIT_SAMPLER) { BX_TRACE("\t%s, %d, %d, %d" , bindDesc.Name , bindDesc.Type , bindDesc.BindPoint , bindDesc.BindCount ); } } } uint16_t count = (uint16_t)uniforms.size(); bx::write(_writer, count); uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0; for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it) { const Uniform& un = *it; uint8_t nameSize = (uint8_t)un.name.size(); bx::write(_writer, nameSize); bx::write(_writer, un.name.c_str(), nameSize); uint8_t type = un.type|fragmentBit; bx::write(_writer, type); bx::write(_writer, un.num); bx::write(_writer, un.regIndex); bx::write(_writer, un.regCount); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() , getUniformTypeName(un.type) , un.num , un.regIndex , un.regCount ); } { ID3DBlob* stripped; hr = D3DStripShader(code->GetBufferPointer() , code->GetBufferSize() , D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_TEST_BLOBS , &stripped ); if (SUCCEEDED(hr) ) { code->Release(); code = stripped; } } uint16_t shaderSize = (uint16_t)code->GetBufferSize(); bx::write(_writer, shaderSize); bx::write(_writer, code->GetBufferPointer(), shaderSize); uint8_t nul = 0; bx::write(_writer, nul); bx::write(_writer, numAttrs); bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) ); bx::write(_writer, size); if (_cmdLine.hasArg('\0', "disasm") ) { ID3DBlob* disasm; D3DDisassemble(code->GetBufferPointer() , code->GetBufferSize() , 0 , NULL , &disasm ); if (NULL != disasm) { std::string disasmfp = _cmdLine.findOption('o'); disasmfp += ".disasm"; writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), (uint32_t)disasm->GetBufferSize() ); disasm->Release(); } } if (NULL != reflect) { reflect->Release(); } if (NULL != errorMsg) { errorMsg->Release(); } code->Release(); return true; }