<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

//#include <d3dcompiler.h>

#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"

#include "include/gpu/GrDirectContext.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/GrAutoLocaleSetter.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrPersistentCacheUtils.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRenderTarget.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DUtil.h"
#include "src/sksl/SkSLCompiler.h"

#include <d3dcompiler.h>

std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
        GrD3DGpu* gpu,
        GrRenderTarget* renderTarget,
        const GrProgramDesc& desc,
        const GrProgramInfo& programInfo) {
    // ensure that we use "." as a decimal separator when creating SkSL code
    GrAutoLocaleSetter als("C");

    // create a builder.  This will be handed off to effects so they can use it to add
    // uniforms, varyings, textures, etc
    GrD3DPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);

    if (!builder.emitAndInstallProcs()) {
        return nullptr;
    }

    return builder.finalize();
}

GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(GrD3DGpu* gpu,
                                                     GrRenderTarget* renderTarget,
                                                     const GrProgramDesc& desc,
                                                     const GrProgramInfo& programInfo)
        : INHERITED(renderTarget, desc, programInfo)
        , fGpu(gpu)
        , fVaryingHandler(this)
        , fUniformHandler(this) {}

const GrCaps* GrD3DPipelineStateBuilder::caps() const {
    return fGpu->caps();
}

SkSL::Compiler* GrD3DPipelineStateBuilder::shaderCompiler() const {
    return fGpu->shaderCompiler();
}

void GrD3DPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 0");
}

void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 1");
}

static gr_cp<ID3DBlob> GrCompileHLSLShader(GrD3DGpu* gpu,
                                           const SkSL::String& hlsl,
                                           SkSL::ProgramKind kind) {
    TRACE_EVENT0("skia.shaders", "driver_compile_shader");
    const char* compileTarget = nullptr;
    switch (kind) {
        case SkSL::ProgramKind::kVertex:
            compileTarget = "vs_5_1";
            break;
        case SkSL::ProgramKind::kGeometry:
            compileTarget = "gs_5_1";
            break;
        case SkSL::ProgramKind::kFragment:
            compileTarget = "ps_5_1";
            break;
        default:
            SkUNREACHABLE;
    }

    uint32_t compileFlags = 0;
#ifdef SK_DEBUG
    // Enable better shader debugging with the graphics debugging tools.
    compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
    // SPRIV-cross does matrix multiplication expecting row major matrices
    compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;

    gr_cp<ID3DBlob> shader;
    gr_cp<ID3DBlob> errors;
    HRESULT hr = D3DCompile(hlsl.c_str(), hlsl.length(), nullptr, nullptr, nullptr, "main",
                            compileTarget, compileFlags, 0, &shader, &errors);
    if (!SUCCEEDED(hr)) {
        gpu->getContext()->priv().getShaderErrorHandler()->compileError(
                hlsl.c_str(), reinterpret_cast<char*>(errors->GetBufferPointer()));
    }
    return shader;
}

bool GrD3DPipelineStateBuilder::loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID3DBlob> shaders[]) {

    SkSL::String hlsl[kGrShaderTypeCount];
    SkSL::Program::Inputs inputs[kGrShaderTypeCount];

    if (!GrPersistentCacheUtils::UnpackCachedShaders(reader, hlsl, inputs, kGrShaderTypeCount)) {
        return false;
    }

    auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
        if (inputs[shaderType].fRTHeight) {
            this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
        }
        shaders[shaderType] = GrCompileHLSLShader(fGpu, hlsl[shaderType], kind);
        return shaders[shaderType].get();
    };

    return compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) &&
           compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType) &&
           (hlsl[kGeometry_GrShaderType].empty() ||
            compile(SkSL::ProgramKind::kGeometry, kGeometry_GrShaderType));
}

gr_cp<ID3DBlob> GrD3DPipelineStateBuilder::compileD3DProgram(
        SkSL::ProgramKind kind,
        const SkSL::String& sksl,
        const SkSL::Program::Settings& settings,
        SkSL::Program::Inputs* outInputs,
        SkSL::String* outHLSL) {
    auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
    std::unique_ptr<SkSL::Program> program = fGpu->shaderCompiler()->convertProgram(
            kind, sksl, settings);
    if (!program) {
        errorHandler->compileError(sksl.c_str(),
                                   fGpu->shaderCompiler()->errorText().c_str());
        return gr_cp<ID3DBlob>();
    }
    *outInputs = program->fInputs;
    if (!fGpu->shaderCompiler()->toHLSL(*program, outHLSL)) {
        errorHandler->compileError(sksl.c_str(),
                                   fGpu->shaderCompiler()->errorText().c_str());
        return gr_cp<ID3DBlob>();
    }

    if (program->fInputs.fRTHeight) {
        this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
    }

    return GrCompileHLSLShader(fGpu, *outHLSL, kind);
}

static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
    switch (type) {
    case kFloat_GrVertexAttribType:
        return DXGI_FORMAT_R32_FLOAT;<commit_msg>Clean up D3D12 shader compilation<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

//#include <d3dcompiler.h>

#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"

#include "include/gpu/GrDirectContext.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/GrAutoLocaleSetter.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrPersistentCacheUtils.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRenderTarget.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DUtil.h"
#include "src/sksl/SkSLCompiler.h"

#include <d3dcompiler.h>

std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
        GrD3DGpu* gpu,
        GrRenderTarget* renderTarget,
        const GrProgramDesc& desc,
        const GrProgramInfo& programInfo) {
    // ensure that we use "." as a decimal separator when creating SkSL code
    GrAutoLocaleSetter als("C");

    // create a builder.  This will be handed off to effects so they can use it to add
    // uniforms, varyings, textures, etc
    GrD3DPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);

    if (!builder.emitAndInstallProcs()) {
        return nullptr;
    }

    return builder.finalize();
}

GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(GrD3DGpu* gpu,
                                                     GrRenderTarget* renderTarget,
                                                     const GrProgramDesc& desc,
                                                     const GrProgramInfo& programInfo)
        : INHERITED(renderTarget, desc, programInfo)
        , fGpu(gpu)
        , fVaryingHandler(this)
        , fUniformHandler(this) {}

const GrCaps* GrD3DPipelineStateBuilder::caps() const {
    return fGpu->caps();
}

SkSL::Compiler* GrD3DPipelineStateBuilder::shaderCompiler() const {
    return fGpu->shaderCompiler();
}

void GrD3DPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 0");
}

void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 1");
}

// Print the source code for all shaders generated.
static const bool gPrintSKSL = false;
static const bool gPrintHLSL = false;

static gr_cp<ID3DBlob> GrCompileHLSLShader(GrD3DGpu* gpu,
                                           const SkSL::String& hlsl,
                                           SkSL::ProgramKind kind) {
    TRACE_EVENT0("skia.shaders", "driver_compile_shader");
    const char* compileTarget = nullptr;
    switch (kind) {
        case SkSL::ProgramKind::kVertex:
            compileTarget = "vs_5_1";
            break;
        case SkSL::ProgramKind::kGeometry:
            compileTarget = "gs_5_1";
            break;
        case SkSL::ProgramKind::kFragment:
            compileTarget = "ps_5_1";
            break;
        default:
            SkUNREACHABLE;
    }

    uint32_t compileFlags = 0;
#ifdef SK_DEBUG
    // Enable better shader debugging with the graphics debugging tools.
    compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
    // SPRIV-cross does matrix multiplication expecting row major matrices
    compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;

    gr_cp<ID3DBlob> shader;
    gr_cp<ID3DBlob> errors;
    HRESULT hr = D3DCompile(hlsl.c_str(), hlsl.length(), nullptr, nullptr, nullptr, "main",
                            compileTarget, compileFlags, 0, &shader, &errors);
    if (!SUCCEEDED(hr)) {
        gpu->getContext()->priv().getShaderErrorHandler()->compileError(
                hlsl.c_str(), reinterpret_cast<char*>(errors->GetBufferPointer()));
    }
    return shader;
}

bool GrD3DPipelineStateBuilder::loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID3DBlob> shaders[]) {

    SkSL::String hlsl[kGrShaderTypeCount];
    SkSL::Program::Inputs inputs[kGrShaderTypeCount];

    if (!GrPersistentCacheUtils::UnpackCachedShaders(reader, hlsl, inputs, kGrShaderTypeCount)) {
        return false;
    }

    auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
        if (inputs[shaderType].fRTHeight) {
            this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
        }
        shaders[shaderType] = GrCompileHLSLShader(fGpu, hlsl[shaderType], kind);
        return shaders[shaderType].get();
    };

    return compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) &&
           compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType) &&
           (hlsl[kGeometry_GrShaderType].empty() ||
            compile(SkSL::ProgramKind::kGeometry, kGeometry_GrShaderType));
}

gr_cp<ID3DBlob> GrD3DPipelineStateBuilder::compileD3DProgram(
        SkSL::ProgramKind kind,
        const SkSL::String& sksl,
        const SkSL::Program::Settings& settings,
        SkSL::Program::Inputs* outInputs,
        SkSL::String* outHLSL) {
#ifdef SK_DEBUG
    SkSL::String src = GrShaderUtils::PrettyPrint(sksl);
#else
    const SkSL::String& src = sksl;
#endif

    std::unique_ptr<SkSL::Program> program = fGpu->shaderCompiler()->convertProgram(
            kind, src, settings);
    if (!program || !fGpu->shaderCompiler()->toHLSL(*program, outHLSL)) {
        auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
        errorHandler->compileError(src.c_str(),
                                   fGpu->shaderCompiler()->errorText().c_str());
        return gr_cp<ID3DBlob>();
    }
    *outInputs = program->fInputs;

    if (gPrintSKSL || gPrintHLSL) {
        GrShaderUtils::PrintShaderBanner(kind);
        if (gPrintSKSL) {
            SkDebugf("SKSL:\n");
            GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(sksl));
        }
        if (gPrintHLSL) {
            SkDebugf("HLSL:\n");
            GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(*outHLSL));
        }
    }

    if (program->fInputs.fRTHeight) {
        this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
    }

    return GrCompileHLSLShader(fGpu, *outHLSL, kind);
}

static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
    switch (type) {
    case kFloat_GrVertexAttribType:
        return DXGI_FORMAT_R32_FLOAT;
{'fraction_non_alphanumeric': 0.11321352228643813, 'fraction_numerical': 0.010133797799065791, 'mean_word_length': 3.098637248539909, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 23, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2389211', 'n_tokens_mistral': 4034, 'n_tokens_neox': 3962, 'n_words': 721}