<commit_before>//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "compiler/Uniform.h"
#include "common/mathutil.h"
#include "common/utilities.h"

namespace sh
{

Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex)
{
    this->type = type;
    this->precision = precision;
    this->name = name;
    this->arraySize = arraySize;
    this->registerIndex = registerIndex;
}

BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
    : offset(offset),
      arrayStride(arrayStride),
      matrixStride(matrixStride),
      isRowMajorMatrix(isRowMajorMatrix)
{
}

const BlockMemberInfo BlockMemberInfo::defaultBlockInfo(-1, -1, -1, false);

InterfaceBlock::InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex)
    : name(name),
      arraySize(arraySize),
      layout(BLOCKLAYOUT_SHARED),
      registerIndex(registerIndex)
{
}

// Use the same layout for packed and shared
void InterfaceBlock::setBlockLayout(BlockLayoutType newLayout)
{
    layout = newLayout;

    const size_t componentSize = 4;
    unsigned int currentOffset = 0;

    blockInfo.clear();
    getBlockLayoutInfo(activeUniforms, &currentOffset);

    dataSize = currentOffset * componentSize;
}

void InterfaceBlock::getBlockLayoutInfo(const sh::ActiveUniforms &fields, unsigned int *currentOffset)
{
    const size_t componentSize = 4;

    // TODO: row major matrices
    bool isRowMajorMatrix = false;

    for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
    {
        int arrayStride;
        int matrixStride;

        const sh::Uniform &uniform = fields[fieldIndex];

        if (getBlockLayoutInfo(uniform, currentOffset, &arrayStride, &matrixStride))
        {
            const BlockMemberInfo memberInfo(*currentOffset * componentSize, arrayStride * componentSize, matrixStride * componentSize, isRowMajorMatrix);
            blockInfo.push_back(memberInfo);

            if (uniform.arraySize > 0)
            {
                *currentOffset += arrayStride * uniform.arraySize;
            }
            else if (gl::IsMatrixType(uniform.type))
            {
                const int componentGroups = (isRowMajorMatrix ? gl::VariableRowCount(uniform.type) : gl::VariableColumnCount(uniform.type));
                *currentOffset += matrixStride * componentGroups;
            }
            else
            {
                *currentOffset += gl::UniformComponentCount(uniform.type);
            }
        }
    }
}

bool InterfaceBlock::getBlockLayoutInfo(const sh::Uniform &uniform, unsigned int *currentOffset, int *arrayStrideOut, int *matrixStrideOut)
{
    if (!uniform.fields.empty())
    {
        if (uniform.arraySize > 0)
        {
            for (unsigned int arrayElement = 0; arrayElement < uniform.arraySize; arrayElement++)
            {
                getBlockLayoutInfo(uniform.fields, currentOffset);
            }
        }
        else
        {
            getBlockLayoutInfo(uniform.fields, currentOffset);
        }
        return false;
    }

    switch (layout)
    {
      case BLOCKLAYOUT_SHARED:
      case BLOCKLAYOUT_PACKED:
        getD3DLayoutInfo(uniform, currentOffset, arrayStrideOut, matrixStrideOut);
        return true;

      case BLOCKLAYOUT_STANDARD:
        getStandardLayoutInfo(uniform, currentOffset, arrayStrideOut, matrixStrideOut);
        return true;

      default:
        UNREACHABLE();
        return false;
    }<commit_msg>Fix alignment of HLSL packed structs in interface blocks.<commit_after>//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "compiler/Uniform.h"
#include "common/mathutil.h"
#include "common/utilities.h"

namespace sh
{

Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex)
{
    this->type = type;
    this->precision = precision;
    this->name = name;
    this->arraySize = arraySize;
    this->registerIndex = registerIndex;
}

BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
    : offset(offset),
      arrayStride(arrayStride),
      matrixStride(matrixStride),
      isRowMajorMatrix(isRowMajorMatrix)
{
}

const BlockMemberInfo BlockMemberInfo::defaultBlockInfo(-1, -1, -1, false);

InterfaceBlock::InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex)
    : name(name),
      arraySize(arraySize),
      layout(BLOCKLAYOUT_SHARED),
      registerIndex(registerIndex)
{
}

// Use the same layout for packed and shared
void InterfaceBlock::setBlockLayout(BlockLayoutType newLayout)
{
    layout = newLayout;

    const size_t componentSize = 4;
    unsigned int currentOffset = 0;

    blockInfo.clear();
    getBlockLayoutInfo(activeUniforms, &currentOffset);

    dataSize = currentOffset * componentSize;
}

void InterfaceBlock::getBlockLayoutInfo(const sh::ActiveUniforms &fields, unsigned int *currentOffset)
{
    const size_t componentSize = 4;

    // TODO: row major matrices
    bool isRowMajorMatrix = false;

    for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
    {
        int arrayStride;
        int matrixStride;

        const sh::Uniform &uniform = fields[fieldIndex];

        if (getBlockLayoutInfo(uniform, currentOffset, &arrayStride, &matrixStride))
        {
            const BlockMemberInfo memberInfo(*currentOffset * componentSize, arrayStride * componentSize, matrixStride * componentSize, isRowMajorMatrix);
            blockInfo.push_back(memberInfo);

            if (uniform.arraySize > 0)
            {
                *currentOffset += arrayStride * uniform.arraySize;
            }
            else if (gl::IsMatrixType(uniform.type))
            {
                const int componentGroups = (isRowMajorMatrix ? gl::VariableRowCount(uniform.type) : gl::VariableColumnCount(uniform.type));
                *currentOffset += matrixStride * componentGroups;
            }
            else
            {
                *currentOffset += gl::UniformComponentCount(uniform.type);
            }
        }
    }
}

bool InterfaceBlock::getBlockLayoutInfo(const sh::Uniform &uniform, unsigned int *currentOffset, int *arrayStrideOut, int *matrixStrideOut)
{
    if (!uniform.fields.empty())
    {
        const unsigned int elementCount = std::max(1u, uniform.arraySize);

        for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
        {
            // align struct to register size
            *currentOffset = rx::roundUp(*currentOffset, 4u);
            getBlockLayoutInfo(uniform.fields, currentOffset);
        }

        return false;
    }

    switch (layout)
    {
      case BLOCKLAYOUT_SHARED:
      case BLOCKLAYOUT_PACKED:
        getD3DLayoutInfo(uniform, currentOffset, arrayStrideOut, matrixStrideOut);
        return true;

      case BLOCKLAYOUT_STANDARD:
        getStandardLayoutInfo(uniform, currentOffset, arrayStrideOut, matrixStrideOut);
        return true;

      default:
        UNREACHABLE();
        return false;
    }
{'fraction_non_alphanumeric': 0.09304207119741101, 'fraction_numerical': 0.004180151024811219, 'mean_word_length': 2.9494142705005326, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4193826', 'n_tokens_mistral': 2082, 'n_tokens_neox': 1994, 'n_words': 504}