void ShaderReflection::Reflect(ID3D10Blob* shader) {
	ID3D11ShaderReflection* reflector = 0;
	D3D11_SIGNATURE_PARAMETER_DESC input, output;
	D3D11_SHADER_INPUT_BIND_DESC resource; //Bind point is the register location


	D3DReflect(shader->GetBufferPointer(), shader->GetBufferSize(), 
		IID_ID3D11ShaderReflection, (void**)&reflector);

	reflector->GetDesc(&shaderDesc);

	inputParams.paramCount = shaderDesc.InputParameters;
	inputParams.params = new D3D11_SIGNATURE_PARAMETER_DESC[inputParams.paramCount];
	for(u32 i = 0; i < shaderDesc.InputParameters; ++i) {
		reflector->GetInputParameterDesc(i, &input);
		inputParams.params[i] = input;
	}

	outputParams.paramCount = shaderDesc.OutputParameters;
	outputParams.params = new D3D11_SIGNATURE_PARAMETER_DESC[outputParams.paramCount];
	for(u32 i = 0; i < shaderDesc.OutputParameters; ++i) {
		reflector->GetOutputParameterDesc(i, &output);
		outputParams.params[i] = output;
	}

	for(u32 i = 0; i < shaderDesc.BoundResources; ++i) {
		reflector->GetResourceBindingDesc(i, &resource);
		
		if(resource.Type == D3D_SIT_CBUFFER) {
			ProcessCbuffer(reflector->GetConstantBufferByName(resource.Name));
		}
		else if(resource.Type == D3D_SIT_SAMPLER) {

		}
		else if(resource.Type == D3D_SIT_TEXTURE) {
			
		}
		else {}
	}
}
Example #2
0
void ezShaderCompilerHLSL::ReflectShaderStage(ezShaderProgramData& inout_Data, ezGALShaderStage::Enum Stage)
{
  ID3D11ShaderReflection* pReflector = nullptr;

  auto byteCode = inout_Data.m_StageBinary[Stage].GetByteCode();
  D3DReflect(byteCode.GetData(), byteCode.GetCount(), IID_ID3D11ShaderReflection, (void**)&pReflector);

  D3D11_SHADER_DESC shaderDesc;
  pReflector->GetDesc(&shaderDesc);

  for (ezUInt32 r = 0; r < shaderDesc.BoundResources; ++r)
  {
    D3D11_SHADER_INPUT_BIND_DESC shaderInputBindDesc;
    pReflector->GetResourceBindingDesc(r, &shaderInputBindDesc);

    // ezLog::Info("Bound Resource: '{0}' at slot {1} (Count: {2}, Flags: {3})", sibd.Name, sibd.BindPoint, sibd.BindCount, sibd.uFlags);

    ezShaderResourceBinding shaderResourceBinding;
    shaderResourceBinding.m_Type = ezShaderResourceBinding::Unknown;
    shaderResourceBinding.m_iSlot = shaderInputBindDesc.BindPoint;
    shaderResourceBinding.m_sName.Assign(shaderInputBindDesc.Name);

    if (shaderInputBindDesc.Type == D3D_SIT_TEXTURE)
    {
      switch (shaderInputBindDesc.Dimension)
      {
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1D:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture1D;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1DARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture1DArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2D:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture2D;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture2DArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DMS:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture2DMS;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DMSARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture2DMSArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE3D:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::Texture3D;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURECUBE:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::TextureCube;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURECUBEARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::TextureCubeArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_BUFFER:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::GenericBuffer;
          break;

        default:
          EZ_ASSERT_NOT_IMPLEMENTED;
          break;
      }
    }

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_RWTYPED)
    {
      switch (shaderInputBindDesc.Dimension)
      {
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1D:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::RWTexture1D;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1DARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::RWTexture1DArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2D:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::RWTexture2D;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DARRAY:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::RWTexture2DArray;
          break;
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_BUFFER:
        case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_BUFFEREX:
          shaderResourceBinding.m_Type = ezShaderResourceBinding::RWBuffer;
          break;

        default:
          EZ_ASSERT_NOT_IMPLEMENTED;
          break;
      }
    }

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_RWSTRUCTURED)
      shaderResourceBinding.m_Type = ezShaderResourceBinding::RWStructuredBuffer;

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_RWBYTEADDRESS)
      shaderResourceBinding.m_Type = ezShaderResourceBinding::RWRawBuffer;

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_APPEND_STRUCTURED)
      shaderResourceBinding.m_Type = ezShaderResourceBinding::RWAppendBuffer;

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_CONSUME_STRUCTURED)
      shaderResourceBinding.m_Type = ezShaderResourceBinding::RWConsumeBuffer;

    else if (shaderInputBindDesc.Type == D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER)
      shaderResourceBinding.m_Type = ezShaderResourceBinding::RWStructuredBufferWithCounter;

    else if (shaderInputBindDesc.Type == D3D_SIT_CBUFFER)
    {
      shaderResourceBinding.m_Type = ezShaderResourceBinding::ConstantBuffer;
      shaderResourceBinding.m_pLayout =
        ReflectConstantBufferLayout(inout_Data.m_StageBinary[Stage], pReflector->GetConstantBufferByName(shaderInputBindDesc.Name));
    }
    else if (shaderInputBindDesc.Type == D3D_SIT_SAMPLER)
    {
      shaderResourceBinding.m_Type = ezShaderResourceBinding::Sampler;
      if (ezStringUtils::EndsWith(shaderInputBindDesc.Name, "_AutoSampler"))
      {
        ezStringBuilder sb = shaderInputBindDesc.Name;
        sb.Shrink(0, ezStringUtils::GetStringElementCount("_AutoSampler"));
        shaderResourceBinding.m_sName.Assign(sb.GetData());
      }
    }
    else
    {
      shaderResourceBinding.m_Type = ezShaderResourceBinding::GenericBuffer;
    }

    if (shaderResourceBinding.m_Type != ezShaderResourceBinding::Unknown)
    {
      inout_Data.m_StageBinary[Stage].AddShaderResourceBinding(shaderResourceBinding);
    }
  }

  pReflector->Release();
}
Example #3
0
// Requires the compiled shaders (.cso files)
DXShader::DXShader( string vertexPath, string fragmentPath )
{
	HRESULT result;
	ID3DBlob* shaderCompileErrors;

	// Layout description, must match layout in vertex shader
	const int numLayoutElements = 3;
	const D3D11_INPUT_ELEMENT_DESC vLayout[] =
	{
/*POS*/		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
/*UV*/		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
/*NORMAL*/	{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	// ---- Load Vertex Shader
	ID3DBlob* vsb;
	wstring wVertexPath( vertexPath.begin(), vertexPath.end() );
	ShaderInclude include( File( vertexPath ).GetDirectory() );
	//D3DReadFileToBlob( wVertexPath.c_str(), &vsb );
	result = D3DCompileFromFile( wVertexPath.c_str(),
								NULL,
								&include,
								"main",
								"vs_5_0",
								D3DCOMPILE_ENABLE_STRICTNESS,
								0,
								&vsb,
								&shaderCompileErrors );

	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Error compiling vertex shader\n" + vertexPath );
		OutputController::PrintMessage( OutputType::Error, (char*)(shaderCompileErrors->GetBufferPointer()) );
	}
	
	result = AdapterController::Get()->GetDevice().dx->CreateVertexShader( vsb->GetBufferPointer(), 
																vsb->GetBufferSize(),
																NULL,
																&vertexShader );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create vertex shader." );
	}

	// Create Input Layout
	result = AdapterController::Get()->GetDevice().dx->CreateInputLayout( vLayout,
																numLayoutElements,//ARRAYSIZE(vertexLayout),
																vsb->GetBufferPointer(),
																vsb->GetBufferSize(),
																&vertexLayout );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create input layout." );
	}
	

	// ---- Load Pixel Shader
	ID3DBlob* psb;
	wstring wPixelPath( fragmentPath.begin(), fragmentPath.end() );
	//D3DReadFileToBlob( wPixelPath.c_str(), &psb );
	result = D3DCompileFromFile( wPixelPath.c_str(),
								NULL,
								&include,
								"main",
								"ps_5_0",
								D3DCOMPILE_ENABLE_STRICTNESS,
								0,
								&psb,
								&shaderCompileErrors );

	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Error compiling fragment shader\n" + fragmentPath );
		OutputController::PrintMessage( OutputType::Error, (gChar*)(shaderCompileErrors->GetBufferPointer()) );
	}

	result = AdapterController::Get()->GetDevice().dx->CreatePixelShader( psb->GetBufferPointer(),
																psb->GetBufferSize(),
																NULL,
																&pixelShader );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create fragment shader." );
	}

	// get constant buffer variables
	ID3D11ShaderReflection* vsReflection = nullptr;
	D3D11Reflect( vsb->GetBufferPointer(), vsb->GetBufferSize(), &vsReflection );
	D3D11_SHADER_BUFFER_DESC vsShaderBufferDesc;
	vsReflection->GetConstantBufferByName( "uniforms" )->GetDesc( &vsShaderBufferDesc );
	vsShaderBufferDesc.Name;
	UINT numVariables = vsShaderBufferDesc.Variables;
	ID3D11ShaderReflectionVariable* var2 = vsReflection->GetConstantBufferByName( "uniforms" )->GetVariableByIndex( 2 );
	
	D3D11_SHADER_VARIABLE_DESC var2Desc;
	var2->GetDesc( &var2Desc );
	var2Desc.Name;
	var2Desc.Size;

	ID3D11ShaderReflectionType* var2Type = var2->GetType();
	var2Type->GetMemberTypeByIndex(0);
	

	

	// ---- Create Sampler State
	D3D11_SAMPLER_DESC samplerDesc;
	samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.MipLODBias = 0.0f;
	samplerDesc.MaxAnisotropy = 1;
	samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	samplerDesc.BorderColor[0] = 0;
	samplerDesc.BorderColor[1] = 0;
	samplerDesc.BorderColor[2] = 0;
	samplerDesc.BorderColor[3] = 0;
	samplerDesc.MinLOD = 0;
	samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

	result = AdapterController::Get()->GetDevice().dx->CreateSamplerState( &samplerDesc, &samplerState );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create sampler state." );
	}

	// release unneeded buffers
	ReleaseCOMobjMacro( psb );
	ReleaseCOMobjMacro( vsb );
	ReleaseCOMobjMacro( shaderCompileErrors );

	// TEMPORARY BUFFER TO BE REMOVED FROM C++ SIDE
	auto buf = new ConstBuffer;
	buf->totalSize = 0;
	buf->AddProperty( "modelViewProj", sizeof(Matrix4) );
	buf->AddProperty( "rotationMatrix", sizeof(Matrix4) );
	buf->AddProperty( "ambientLight", AmbientLight::size );
	buf->AddProperty( "dirLight", DirectionalLight::size );

	RegisterConstBuffer( "uniforms", buf );
	delete buf;
}
//-------------------------------------------------------------------------------
// @ IvConstantTableD3D11::Create()
//-------------------------------------------------------------------------------
// Get the constant table for this shader
//-------------------------------------------------------------------------------
IvConstantTableD3D11*
IvConstantTableD3D11::Create(ID3D11Device* device, ID3DBlob* code)
{
    ID3D11ShaderReflection* pReflector = nullptr;
    D3DReflect(code->GetBufferPointer(), code->GetBufferSize(),
        IID_ID3D11ShaderReflection, (void**)&pReflector);

    // first get constant table
    IvConstantTableD3D11* table = new IvConstantTableD3D11();

    ID3D11ShaderReflectionConstantBuffer* globalConstants =
        pReflector->GetConstantBufferByName("$Globals");
    D3D11_SHADER_BUFFER_DESC constantBufferDesc = { 0 };
    HRESULT hr = globalConstants->GetDesc(&constantBufferDesc);
    if (FAILED(hr))
    {
        // no constants in this shader
        goto get_textures;
    }

    table->mBacking = new char[constantBufferDesc.Size];
    table->mBackingSize = constantBufferDesc.Size;
    if (nullptr == table->mBacking)
    {
        delete table;
        pReflector->Release();
        return nullptr;
    }

    for (unsigned int i = 0; i < constantBufferDesc.Variables; ++i)
    {
        ID3D11ShaderReflectionVariable* var = globalConstants->GetVariableByIndex(i);
        D3D11_SHADER_VARIABLE_DESC varDesc;
        if (FAILED(var->GetDesc(&varDesc)))
        {
            delete table;
            pReflector->Release();
            return nullptr;
        }
        ID3D11ShaderReflectionType* type = var->GetType();
        D3D11_SHADER_TYPE_DESC typeDesc;
        if (FAILED(type->GetDesc(&typeDesc)))
        {
            delete table;
            pReflector->Release();
            return nullptr;
        }

        IvConstantDesc constantDesc;
        constantDesc.mOffset = table->mBacking + varDesc.StartOffset;
        if (typeDesc.Class == D3D_SVC_SCALAR && typeDesc.Type == D3D_SVT_FLOAT)
        {
            constantDesc.mType = IvUniformType::kFloatUniform;
        }
        else if (typeDesc.Class == D3D_SVC_VECTOR && typeDesc.Type == D3D_SVT_FLOAT
            && typeDesc.Columns == 3)
        {
            constantDesc.mType = IvUniformType::kFloat3Uniform;
        }
        else if (typeDesc.Class == D3D_SVC_VECTOR && typeDesc.Type == D3D_SVT_FLOAT
            && typeDesc.Columns == 4)
        {
            constantDesc.mType = IvUniformType::kFloat4Uniform;
        }
        else if ((typeDesc.Class == D3D_SVC_MATRIX_ROWS || typeDesc.Class == D3D_SVC_MATRIX_COLUMNS)
            && typeDesc.Type == D3D_SVT_FLOAT
            && typeDesc.Rows == 4 && typeDesc.Columns == 4)
        {
            constantDesc.mType = IvUniformType::kFloatMatrix44Uniform;
        }
        else
        {
            // unsupported uniform type
            delete table;
            pReflector->Release();
            return nullptr;
        }
        constantDesc.mCount = typeDesc.Elements != 0 ? typeDesc.Elements : 1;

        table->mConstants[varDesc.Name] = constantDesc;
    }

    D3D11_BUFFER_DESC cbDesc;
    cbDesc.ByteWidth = constantBufferDesc.Size;
    cbDesc.Usage = D3D11_USAGE_DYNAMIC;
    cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    cbDesc.MiscFlags = 0;
    cbDesc.StructureByteStride = 0;

    if (FAILED(device->CreateBuffer(&cbDesc, nullptr, &table->mBuffer)))
    {
        delete table;
        pReflector->Release();
        return nullptr;
    }

get_textures:
    // now get any textures and samplers
    D3D11_SHADER_DESC shaderDesc = { 0 };
    hr = pReflector->GetDesc(&shaderDesc);
    if (FAILED(hr))
    {
        pReflector->Release();
        return table;
    }
    int resourceCount = shaderDesc.BoundResources;

    for (int i = 0; i < resourceCount; ++i) 
    {
        D3D11_SHADER_INPUT_BIND_DESC bindingDesc = { 0 };
        pReflector->GetResourceBindingDesc(i, &bindingDesc);
        if (bindingDesc.Type == D3D_SIT_TEXTURE && bindingDesc.ReturnType == D3D_RETURN_TYPE_FLOAT
            && bindingDesc.Dimension == D3D_SRV_DIMENSION_TEXTURE2D && bindingDesc.NumSamples == -1
            && bindingDesc.BindCount == 1)
        {
            IvConstantDesc& constantDesc = table->mConstants[bindingDesc.Name];
            constantDesc.mType = IvUniformType::kTextureUniform;
            constantDesc.mTextureSlot = bindingDesc.BindPoint;
        }
        else if (bindingDesc.Type == D3D_SIT_SAMPLER && bindingDesc.BindCount == 1)
        {
            char strippedName[256];
            const char* samplerKeyword = strstr(bindingDesc.Name, "Sampler");
            strncpy(strippedName, bindingDesc.Name, samplerKeyword - bindingDesc.Name);
            strippedName[samplerKeyword - bindingDesc.Name] = '\0';
            IvConstantDesc& constantDesc = table->mConstants[strippedName];
            constantDesc.mType = IvUniformType::kTextureUniform;
            constantDesc.mSamplerSlot = bindingDesc.BindPoint;
        }
        else if (bindingDesc.Type == D3D_SIT_CBUFFER && !_strnicmp(bindingDesc.Name, "$Globals", 8))
        {
            // ignore this, we handled it above
        }
        else
        {
            // unsupported resource type
            delete table;
            pReflector->Release();
            return nullptr;
        }
    }

    pReflector->Release();

    return table;
}