Example #1
0
// --------------------------------------------------------
// 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;
}
Example #2
0
Shader::Shader (ShaderType in_shader_type, const ShaderCodePtr& in_code, ShaderLibrary& library)
  : DeviceObject (in_code->GetDeviceManager ())
  , type (in_shader_type)
  , code (in_code)
{
  try
  {
    if (!code)
      throw xtl::make_null_argument_exception ("", "code");

    ID3D11Device& device = GetDevice ();

      //компиляция шейдера

    switch (type)
    {
      case ShaderType_Compute:
      {
        ID3D11ComputeShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreateComputeShader", device.CreateComputeShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreateComputeShader failed");
        
        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      case ShaderType_Domain:
      {
        ID3D11DomainShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreateDomainShader", device.CreateDomainShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreateDomainShader failed");
        
        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      case ShaderType_Geometry:
      {
        ID3D11GeometryShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreateGeometryShader", device.CreateGeometryShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreateGeometryShader failed");
        
        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      case ShaderType_Hull:
      {
        ID3D11HullShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreateHullShader", device.CreateHullShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreateHullShader failed");
        
        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      case ShaderType_Pixel:
      {
        ID3D11PixelShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreatePixelShader", device.CreatePixelShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreatePixelShader failed");
        
        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      case ShaderType_Vertex:
      {
        ID3D11VertexShader* dx_shader = 0;

        check_errors ("ID3D11Device::CreateVertexShader", device.CreateVertexShader (code->GetCompiledData (), code->GetCompiledDataSize (), 0, &dx_shader));

        if (!dx_shader)
          throw xtl::format_operation_exception ("", "ID3D11Device::CreateVertexShader failed");

        shader = DxDeviceChildPtr (dx_shader, false);

        break;
      }
      default:
        throw xtl::make_argument_exception ("", "shader_type");
    }

      //получение информации о шейдере

    ID3D11ShaderReflection* reflector = 0;
   
    check_errors ("D3DReflect", GetDeviceManager ().GetLibrary ().D3DReflect (code->GetCompiledData (), code->GetCompiledDataSize (), IID_ID3D11ShaderReflection, (void**)&reflector));

    if (!reflector)
      throw xtl::format_operation_exception ("", "D3DReflect failed");

    D3D11_SHADER_DESC desc;

    check_errors ("ID3D11ShaderReflection::GetDesc", reflector->GetDesc (&desc));

      //получение информации о константных буферах

    buffer_layouts.reserve (desc.ConstantBuffers);

    for (size_t i=0; i<desc.ConstantBuffers; i++)
    {
      ID3D11ShaderReflectionConstantBuffer* buffer = reflector->GetConstantBufferByIndex (i);

      if (!buffer)
        throw xtl::format_operation_exception ("", "ID3D11ShaderReflection::GetConstantBufferByIndex failed");

      ConstantBufferLayoutPtr layout (new ConstantBufferLayout (*buffer), false);

      layout = library.AddConstantBufferLayout (layout);

      buffer_layouts.push_back (layout);
    }
  }
  catch (xtl::exception& e)
  {
    e.touch ("render::low_level::dx11::Shader::Shader");
    throw;
  }
}
Example #3
0
int main(void)
{
    char const *verbose_var = getenv("D3D4LINUX_VERBOSE");
    if (!verbose_var || *verbose_var != '1')
        dup2(open("/dev/null", O_WRONLY), STDERR_FILENO);

    HMODULE lib = LoadLibrary("d3dcompiler_43.dll");

    /* Ensure stdout is in binary mode */
    setmode(fileno(stdout), O_BINARY);
    setmode(fileno(stdin), O_BINARY);

    int syscall = read_integer();
    int marker = 0;

    if (syscall == D3D4LINUX_COMPILE)
    {
        HRESULT (*compile)(void const *pSrcData, size_t SrcDataSize,
                           char const *pFileName,
                           D3D_SHADER_MACRO const *pDefines,
                           ID3DInclude *pInclude,
                           char const *pEntrypoint, char const *pTarget,
                           uint32_t Flags1, uint32_t Flags2,
                           ID3DBlob **ppCode, ID3DBlob **ppErrorMsgs);
        compile = (decltype(compile))GetProcAddress(lib, "D3DCompile");

        /* This is a D3DCompile() call */
        std::string shader_source = read_string();

        int has_filename = (int)read_integer();
        std::string shader_file;
        if (has_filename)
            shader_file = read_string();

        std::string shader_main = read_string();
        std::string shader_type = read_string();
        uint32_t flags1 = (uint32_t)read_integer();
        uint32_t flags2 = (uint32_t)read_integer();
        marker = (int)read_integer();
        if (marker != D3D4LINUX_FINISHED)
            goto error;

        ID3DBlob *shader_blob = nullptr, *error_blob = nullptr;
        HRESULT ret = compile(shader_source.c_str(), shader_source.size(),
                              shader_file.c_str(),
                              nullptr, /* unimplemented */
                              nullptr, /* unimplemented */
                              shader_main.c_str(),
                              shader_type.c_str(),
                              flags1, flags2, &shader_blob, &error_blob);
        fprintf(stderr, "[D3D4LINUX] D3DCompile([%d bytes], \"%s\", ?, ?, \"%s\", \"%s\", %04x, %04x ) = 0x%08x\n",
                (int)shader_source.size(), has_filename ? shader_file.c_str() : "(nullptr)", shader_main.c_str(), shader_type.c_str(),
                flags1, flags2, (int)ret);

        write_integer(ret);
        write_blob(shader_blob);
        write_blob(error_blob);
        write_integer(D3D4LINUX_FINISHED);

        if (shader_blob)
            shader_blob->Release();
        if (error_blob)
            error_blob->Release();
    }
    else if (syscall == D3D4LINUX_REFLECT)
    {
        HRESULT (*reflect)(void const *pSrcData,
                           size_t SrcDataSize,
                           REFIID pInterface,
                           void **ppReflector);
        reflect = (decltype(reflect))GetProcAddress(lib, "D3DReflect");

        std::vector<uint8_t> *data = read_data();
        int iid_code = read_integer();
        marker = (int)read_integer();
        if (marker != D3D4LINUX_FINISHED)
            goto error;

        char const *iid_name = "";
        IID iid;
        switch (iid_code)
        {
        case D3D4LINUX_IID_SHADER_REFLECTION:
            iid = IID_ID3D11ShaderReflection;
            iid_name = "IID_ID3D11ShaderReflection";
            break;
        default:
            goto error;
        }

        void *object;
        HRESULT ret = reflect(data ? data->data() : nullptr,
                              data ? data->size() : 0,
                              iid, &object);
        fprintf(stderr, "[D3D4LINUX] D3DReflect([%d bytes], %s) = 0x%08x\n",
                data ? (int)data->size() : 0, iid_name, (int)ret);

        write_integer(ret);

        if (iid_code == D3D4LINUX_IID_SHADER_REFLECTION)
        {
            D3D11_SIGNATURE_PARAMETER_DESC param_desc;
            D3D11_SHADER_INPUT_BIND_DESC bind_desc;
            D3D11_SHADER_VARIABLE_DESC variable_desc;
            D3D11_SHADER_BUFFER_DESC buffer_desc;
            D3D11_SHADER_DESC shader_desc;

            ID3D11ShaderReflection *reflector = (ID3D11ShaderReflection *)object;

            /* Serialise D3D11_SHADER_DESC */
            reflector->GetDesc(&shader_desc);
            write_raw(&shader_desc, sizeof(shader_desc));
            write_string(shader_desc.Creator);

            /* Serialize all InputParameterDesc */
            for (uint32_t i = 0; i < shader_desc.InputParameters; ++i)
            {
                reflector->GetInputParameterDesc(i, &param_desc);
                write_raw(&param_desc, sizeof(param_desc));
                write_string(param_desc.SemanticName);
            }

            /* Serialize all OutParameterDesc */
            for (uint32_t i = 0; i < shader_desc.OutputParameters; ++i)
            {
                reflector->GetOutputParameterDesc(i, &param_desc);
                write_raw(&param_desc, sizeof(param_desc));
                write_string(param_desc.SemanticName);
            }

            /* Serialize all ResourceBindingDesc */
            for (uint32_t i = 0; i < shader_desc.BoundResources; ++i)
            {
                reflector->GetResourceBindingDesc(i, &bind_desc);
                write_raw(&bind_desc, sizeof(bind_desc));
                write_string(bind_desc.Name);
            }

            /* Serialize all ConstantBuffer */
            for (uint32_t i = 0; i < shader_desc.ConstantBuffers; ++i)
            {
                ID3D11ShaderReflectionConstantBuffer *cbuffer
                        = reflector->GetConstantBufferByIndex(i);

                /* Serialize D3D11_SHADER_BUFFER_DESC */
                cbuffer->GetDesc(&buffer_desc);
                write_raw(&buffer_desc, sizeof(buffer_desc));
                write_string(buffer_desc.Name);

                /* Serialize all Variable */
                for (uint32_t j = 0; j < buffer_desc.Variables; ++j)
                {
                    ID3D11ShaderReflectionVariable *var
                            = cbuffer->GetVariableByIndex(j);

                    /* Serialize D3D11_SHADER_VARIABLE_DESC */
                    var->GetDesc(&variable_desc);
                    write_raw(&variable_desc, sizeof(variable_desc));
                    write_string(variable_desc.Name);
                    write_integer(variable_desc.DefaultValue ? 1 : 0);
                    if (variable_desc.DefaultValue)
                        write_raw(variable_desc.DefaultValue, variable_desc.Size);
                }
            }
        }

        write_integer(D3D4LINUX_FINISHED);

        delete data;
    }
    else if (syscall == D3D4LINUX_STRIP)
    {
        HRESULT (*strip)(void const *pShaderBytecode,
                         size_t BytecodeLength,
                         uint32_t uStripFlags,
                         ID3DBlob **ppStrippedBlob);
        strip = (decltype(strip))GetProcAddress(lib, "D3DStripShader");

        std::vector<uint8_t> *data = read_data();
        uint32_t flags = (uint32_t)read_integer();
        marker = (int)read_integer();
        if (marker != D3D4LINUX_FINISHED)
            goto error;

        ID3DBlob *strip_blob = nullptr;
        HRESULT ret = strip(data ? data->data() : nullptr,
                            data ? data->size() : 0,
                            flags, &strip_blob);
        fprintf(stderr, "[D3D4LINUX] D3DStripShader([%d bytes], %04x) = 0x%08x\n",
                data ? (int)data->size() : 0, flags, (int)ret);

        write_integer(ret);
        write_blob(strip_blob);
        write_integer(D3D4LINUX_FINISHED);

        if (strip_blob)
            strip_blob->Release();
    }
    else if (syscall == D3D4LINUX_DISASSEMBLE)
    {
        HRESULT (*disas)(void const *pSrcData,
                         size_t SrcDataSize,
                         uint32_t Flags,
                         char const *szComments,
                         ID3DBlob **ppDisassembly);
        disas = (decltype(disas))GetProcAddress(lib, "D3DDisassemble");

        std::vector<uint8_t> *data = read_data();
        uint32_t flags = (uint32_t)read_integer();
        int has_comments = (int)read_integer();
        std::string comments;
        if (has_comments)
            comments = read_string();
        marker = (int)read_integer();
        if (marker != D3D4LINUX_FINISHED)
            goto error;

        ID3DBlob *disas_blob = nullptr;
        HRESULT ret = disas(data ? data->data() : nullptr,
                            data ? data->size() : 0,
                            flags,
                            has_comments ? comments.c_str() : nullptr,
                            &disas_blob);
        fprintf(stderr, "[D3D4LINUX] D3DDisassemble([%d bytes], %04x, %s) = 0x%08x\n",
                data ? (int)data->size() : 0, flags, has_comments ? "[comments]" : "(nullptr)", (int)ret);

        write_integer(ret);
        write_blob(disas_blob);
        write_integer(D3D4LINUX_FINISHED);

        if (disas_blob)
            disas_blob->Release();
    }

    return EXIT_SUCCESS;

error:
    fprintf(stderr, "[D3D4LINUX] Bad message received: %08x %08x\n", syscall, marker);
}