Exemple #1
0
/*************************************************************************/ /**
 ** 
 ** 
 **/ /*************************************************************************/ 
bool D3DShader::compileShader(GLenum type, IContainer *pContainer)
{
DebugBreak();
    if(m_shaderCode.empty())
        return false;
    GLenum shdtype = convertShaderType(type);
    GLhandleARB &shaderObj = m_shaderObjs[shdtype];
    if(!shaderObj)
    {
        //shaderObj = glCreateShaderObjectARB(shdtype);
        // add common parts
        std::string strShd;
        D3DShader *pShd;
        std::vector<codeInfo> codeBlocks;
        int lineOffset = 0;
        for(int i=0; pShd = static_cast<D3DShader*>(pContainer->findShader(i)); i++)
        {
            if(*(pShd->getName()) == '\0')
            {
                strShd += pShd->getShaderCode();
                std::vector<codeInfo>::iterator iCI;
                // calculate all the source code ranges for line # error tracking
                for(iCI = pShd->m_startLineNumbers.begin(); iCI != pShd->m_startLineNumbers.end(); iCI++)
                    codeBlocks.push_back(codeInfo(iCI->lineInFX, iCI->lineinShader + lineOffset, pShd->m_totalLines, iCI->fname.c_str()));
                lineOffset += pShd->m_totalLines;
            }
        }
        // set source
        strShd += m_shaderCode.c_str();

        std::vector<codeInfo>::iterator iCI;
        // calculate all the source code ranges for line # error tracking
        for(iCI = m_startLineNumbers.begin(); iCI != m_startLineNumbers.end(); iCI++)
        {
            codeBlocks.push_back(codeInfo(iCI->lineInFX, iCI->lineinShader + lineOffset, m_totalLines, iCI->fname.c_str()));
        }
        lineOffset += m_totalLines;

        GLint size = strShd.length();
        const /*GLcharARB*/char* progString = strShd.c_str();
        //glShaderSource(shaderObj, 1, &progString, &size);
        //glCompileShader(shaderObj);
        //
        // Get Log even if things went well... for warnings or other messages
        //
        char buf[1024];
        int len = 0;
        //glGetInfoLogARB(shaderObj, 1024, &len, buf);
        if(len)
        {
            char *p = strstr(buf, "0(");
            nvFX::printf("Log for Shader %d:\n", shaderObj);
            if(p==NULL)
                p = strstr(buf, "0:"); // iOS error display
            if(p==NULL)
                nvFX::printf("%s\n", buf);
            while(p)
            {
                *p = '\0';
                p+=2;
                char *pNum = p;
                while((*p != ')')&&(*p != ':'))
                    p++;
                *p++ = '\0';
                int num = atoi(pNum);
                num--;
                int offsetNum = num;
                std::vector<codeInfo>::iterator iCB;
                std::vector<codeInfo>::iterator iCBFound = codeBlocks.end();
                for(iCB = codeBlocks.begin(); iCB != codeBlocks.end(); iCB++)
                    if(num >= iCB->lineinShader)
                    {
                        if(num < (iCB->lineinShader + iCB->totalLinesInFX))
                        {
                            iCBFound = iCB;
                            offsetNum = num - iCB->lineinShader;
                            break;
                        }
                    }
                if/*assert*/( iCBFound != codeBlocks.end() )
                    nvFX::printf("%s(%d)", iCBFound->fname.c_str(), iCBFound->lineInFX + offsetNum);
                else
                    nvFX::printf("()");
                pNum = strstr(p, "0(");
                if(pNum==NULL)
                    pNum = strstr(p, "0:");
                //if(pNum) && (!isalnum(pNum[2])))
                //    pNum = NULL;
                if(pNum) *pNum='\0';
                nvFX::printf("%s", p);
                p = pNum;
            }
            //else nvFX::printf("Log for %d:\n%s\n", shaderObj, buf);
        }
        //
        // Check if we failed
        //
        GLint status = 0;
        //glGetShaderiv(shaderObj, GL_COMPILE_STATUS, &status);
#ifndef SHADERCONCAT_USE
        if(status == 0)
        {
#endif
            //nvFX::printf("Shader code: \n%s\n", strShd.c_str());
            //glDeleteObjectARB(shaderObj);
            shaderObj = 0;
#ifndef SHADERCONCAT_USE
            return false;
        }
#else
        if(status == 0)
            return false;
#endif
    }
    return true;
}
Exemple #2
0
/*************************************************************************/ /**
 ** 
 ** TODO: in SHADERCONCAT_USE, add error log with proper line numbers to nvFX files
 ** 
 **/ /*************************************************************************/ 
bool D3DShaderProgram::bind(IContainer* pContainer)
{
    char buf[1024];
    bool err = false;
    HRESULT hr;
    ID3D1XBlob *shaderErrors;

    //if(m_bound) To remove... can't do this
    //    return true;
    //m_bound = true;

    ID3D1XDevice *pd3d1X = (ID3D1XDevice *)nvFX::getDevice();
#ifdef USE_D3D11
    ID3D11DeviceContext *pd3dDC;
    pd3d1X->GetImmediateContext(&pd3dDC);
#endif

    if(m_linkNeeded)
    {
        //
        // add common parts for line-number conversion :-(
        //
        std::vector<D3DShader::codeInfo> codeBlocks;
        int lineOffset = 0;
        ShaderMap::iterator iShd, iEnd;
        iShd = m_data.shaders.begin();
        iEnd = m_data.shaders.end();
        for(;iShd != iEnd; iShd++)
        {
            for(int n=0; n<(int)iShd->second->m_startLineNumbers.size(); n++)
                codeBlocks.push_back(iShd->second->m_startLineNumbers[n]);
        }
        m_data.code.clear();
        // Add common header code
        D3DShader *pShd;
        for(int i=0; pShd = static_cast<D3DShader*>(pContainer->findShader(i)); i++)
            if(*(pShd->getName()) == '\0')
            {
                if(m_data.shaders.size()>0)
                    m_data.code += pShd->getShaderCode();
            }
        if(m_data.shaders.size()>0)
        {
            iShd = m_data.shaders.begin();
            iEnd = m_data.shaders.end();
            for(;iShd != iEnd; iShd++)
                m_data.code += iShd->second->getShaderCode();
        }
        //
        // Compile the vertex shader
        //
        const char *profile;
        switch(m_shaderFlags)
        {
#pragma MESSAGE(__FILE__"(298) : TODO TODO TODO TODO TODO : allow to chose the shader models!")
        case FX_VERTEX_SHADER_BIT: profile = "vs_4_0"; break;
        case FX_FRAGMENT_SHADER_BIT: profile = "ps_4_0"; break;
        case FX_GEOMETRY_SHADER_BIT: profile = "gs_4_0"; break;
        case FX_TESS_CONTROL_SHADER_BIT: profile = "hs_5_0"; break;
        case FX_TESS_EVALUATION_SHADER_BIT: profile = "ds_5_0"; break;
        default: profile = NULL; assert(1); break;
        }
        /*if*/assert(m_data.shaders.size()>0);
        {
            hr = D3DX1XCompileFromMemory(
              m_data.code.c_str(), m_data.code.size(), "Shader",
              NULL,//CONST D3D1X_SHADER_MACRO*
              NULL, //LPD3D1XINCLUDE pInclude
              "main",
              profile,
              0,//Flags1
              0,//Flags2
              NULL,//ID3DX10ThreadPump *pPump
              &m_data.compiledShader,
              &shaderErrors, NULL);
    //OutputDebugStringA(m_data.code.c_str());
            if(FAILED(hr))
            {
                err = true;
                LPCSTR p = (LPCSTR)shaderErrors->GetBufferPointer();
                replaceLineNumbers(buf, 1024, p, codeBlocks);
                nvFX::printf("Log for Vtx Shader: \n%s\n", buf);
            }
            else
            {
                switch(m_shaderFlags)
                {
                case FX_VERTEX_SHADER_BIT:
                    hr = pd3d1X->CreateVertexShader(m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), 
                    #ifdef USE_D3D11
                    NULL, // This is ID3D11ClassLinkage pointer. TODO: see how to use it later.
                    #endif
                    &m_data.vtxShader);
                    break;
                case FX_FRAGMENT_SHADER_BIT:
                    hr = pd3d1X->CreatePixelShader(m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), 
                    #ifdef USE_D3D11
                    NULL, // This is ID3D11ClassLinkage pointer. TODO: see how to use it later.
                    #endif
                    &m_data.pixShader);
                    break;
                case FX_GEOMETRY_SHADER_BIT:
                    hr = pd3d1X->CreateGeometryShader(m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), 
                    #ifdef USE_D3D11
                    NULL, // This is ID3D11ClassLinkage pointer. TODO: see how to use it later.
                    #endif
                    &m_data.gsShader);
                    break;
                case FX_TESS_CONTROL_SHADER_BIT:
                    //#ifdef USE_D3D11
                    //hr = pd3d1X->CreateHullShader(m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), 
                    //NULL, // This is ID3D11ClassLinkage pointer. TODO: see how to use it later.
                    //&m_data.hullShader);
                    //#else
                    assert(1);
                    //#endif
                case FX_TESS_EVALUATION_SHADER_BIT:
                    //#ifdef USE_D3D11
                    //hr = pd3d1X->CreateDomainShader(m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), 
                    //NULL, // This is ID3D11ClassLinkage pointer. TODO: see how to use it later.
                    //&m_data.evalShader);
                    //#else
                    assert(1);
                    //#endif
                }
                if(FAILED(hr))
                {
                    err = true;
                    LPCSTR p = (LPCSTR)shaderErrors->GetBufferPointer();
                    replaceLineNumbers(buf, 1024, p, codeBlocks);
                    nvFX::printf("Shader creation error : \n%s\n", p);
                }
                // IID_ID3D1XShaderReflection doesn't work... WTF ?!?
                hr = D3DReflect( m_data.compiledShader->GetBufferPointer(), m_data.compiledShader->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&m_data.reflector);
                if(FAILED(hr))
                {
                    err = true;
                    nvFX::printf("Shader reflector failed\n");
                }
                //
                // Let's check if the shader forgot some parameters in $Globals cbuffer
                //
                D3D11_SHADER_DESC sd;
                ID3D1XShaderReflectionConstantBuffer *pCst = NULL;
                m_data.reflector->GetDesc((D3D1X_SHADER_DESC*)&sd);
                D3D1X_SHADER_BUFFER_DESC bufDesc;
                bufDesc.Name = NULL;
                pCst = m_data.reflector->GetConstantBufferByName("$Globals");
                pCst->GetDesc(&bufDesc);
                if(bufDesc.Name && (!strcmp(bufDesc.Name, "$Globals")))
                {
                    nvFX::printf("WARNING: some uniform parameters are outside of any cbuffer and won't be initialized properly : \n");
                    for(int i=0; i<(int)bufDesc.Variables; i++)
                    {
                        ID3D1XShaderReflectionVariable* pVar = pCst->GetVariableByIndex(i);
                        D3D11_SHADER_VARIABLE_DESC vd; // because of a bug...?!?
                        pVar->GetDesc((D3D1X_SHADER_VARIABLE_DESC*)&vd);
                        nvFX::printf("%s\n", vd.Name);
                    }
                }

                if(shaderErrors)
                    shaderErrors->Release();
            }
        } //if(m_data.shaders.size()>0)
        if(err)
            return false;
        else
            m_linkNeeded = false;
    } //if(m_linkNeeded)
    //
    // Activate the shaders
    //
#ifdef USE_D3D11
    // TODO: see how to take advantage of ID3D11ClassInstance * argument !
    switch(m_shaderFlags)
    {
    case FX_VERTEX_SHADER_BIT:
        pd3dDC->VSSetShader(m_data.vtxShader, NULL, 0);
        break;
    case FX_FRAGMENT_SHADER_BIT:
        pd3dDC->PSSetShader(m_data.pixShader, NULL, 0);
        break;
    case FX_GEOMETRY_SHADER_BIT:
        pd3dDC->GSSetShader(m_data.gsShader, NULL, 0);
        break;
    case FX_TESS_CONTROL_SHADER_BIT:
        //pd3dDC->...SetShader(m_data.);
        //break;
    case FX_TESS_EVALUATION_SHADER_BIT:
        //pd3dDC->...SetShader(m_data.);
        //break;
    default:
        assert(1);
    }
#else
    switch(m_shaderFlags)
    {
    case FX_VERTEX_SHADER_BIT:
        pd3d1X->VSSetShader(m_data.vtxShader);
        break;
    case FX_FRAGMENT_SHADER_BIT:
        pd3d1X->PSSetShader(m_data.pixShader);
        break;
    case FX_GEOMETRY_SHADER_BIT:
        pd3d1X->GSSetShader(m_data.gsShader);
        break;
    default:
        assert(1);
    }
#endif
    return true;
}