src/ngfx/porting/d3d/D3DShaderModule.cpp

Functions

Name
template <typename T >
std::unique_ptr< T >
createShaderModule(Device * device, const std::string & filename)

Functions Documentation

function createShaderModule

template <typename T >
static std::unique_ptr< T > createShaderModule(
    Device * device,
    const std::string & filename
)

Source code

/*
 * Copyright 2020 GoPro Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#include "ngfx/porting/d3d/D3DShaderModule.h"
#include "ngfx/core/File.h"
#include "ngfx/core/StringUtil.h"
#include "ngfx/graphics/Config.h"
#include "ngfx/porting/d3d/D3DDebugUtil.h"
#include <d3dcompiler.h>
#include <memory>
using namespace ngfx;
using namespace std;

void D3DShaderModule::initFromFile(const std::string &filename) {
  File file;
#ifdef USE_PRECOMPILED_SHADERS
  file.read(filename + ".dxc");
  initFromByteCode(file.data.get(), file.size);
#else
  compile(filename + ".hlsl");
#endif
}

void D3DShaderModule::compile(const std::string &filename) {
  HRESULT hResult;
  UINT compileFlags = 0;
  if (DEBUG_SHADERS)
    compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
  ComPtr<ID3DBlob> byteCode;
  ComPtr<ID3DBlob> errorBlob;
  std::string target;
  if (strstr(filename.c_str(), "vert"))
    target = "vs_5_1";
  else if (strstr(filename.c_str(), "frag"))
    target = "ps_5_1";
  else if (strstr(filename.c_str(), "comp"))
    target = "cs_5_1";
  hResult = D3DCompileFromFile(StringUtil::toWString(filename).c_str(), nullptr,
                               nullptr, "main", target.c_str(), compileFlags, 0,
                               &byteCode, &errorBlob);
  if (errorBlob) {
    NGFX_ERR("%s %s", (char *)errorBlob->GetBufferPointer(), filename.c_str());
  }
  V0(hResult, "%s", filename.c_str());
  initFromByteCode(byteCode->GetBufferPointer(),
                   uint32_t(byteCode->GetBufferSize()));
}

void D3DShaderModule::initFromByteCode(void *bytecodeData,
                                       uint32_t bytecodeSize) {
  d3dShaderByteCode.pShaderBytecode = malloc(bytecodeSize);
  d3dShaderByteCode.BytecodeLength = bytecodeSize;
  memcpy((void *)d3dShaderByteCode.pShaderBytecode, bytecodeData, bytecodeSize);
}

D3DShaderModule::~D3DShaderModule() {
  if (d3dShaderByteCode.pShaderBytecode) {
    free((void *)d3dShaderByteCode.pShaderBytecode);
  }
}

template <typename T>
static std::unique_ptr<T> createShaderModule(Device *device,
                                             const std::string &filename) {
  auto d3dShaderModule = make_unique<T>();
  d3dShaderModule->initFromFile(filename);
  d3dShaderModule->initBindings(filename + ".hlsl.map");
  return d3dShaderModule;
}

unique_ptr<VertexShaderModule>
VertexShaderModule::create(Device *device, const std::string &filename) {
  return createShaderModule<D3DVertexShaderModule>(device, filename);
}

unique_ptr<FragmentShaderModule>
FragmentShaderModule::create(Device *device, const std::string &filename) {
  return createShaderModule<D3DFragmentShaderModule>(device, filename);
}

unique_ptr<ComputeShaderModule>
ComputeShaderModule::create(Device *device, const std::string &filename) {
  return createShaderModule<D3DComputeShaderModule>(device, filename);
}

Updated on 3 April 2021 at 20:21:51 PDT