Merge branch 'master' of https://github.com/bkaradzic/bgfx.git into shaderc-output-type

This commit is contained in:
Sam Hellawell 2024-10-10 15:26:32 +01:00
commit 7d8d72b8ce
1038 changed files with 31623 additions and 14081 deletions

View File

@ -134,42 +134,6 @@ jobs:
".build/linux64_gcc/bin/geometryc${{ matrix.binsuffix}}" --version
".build/linux64_gcc/bin/shaderc${{ matrix.binsuffix}}" --version
".build/linux64_gcc/bin/texturec${{ matrix.binsuffix}}" --version
wasm:
strategy:
fail-fast: true
matrix:
config: [ debug, release]
name: wasm-${{ matrix.config }}
runs-on: ubuntu-22.04
steps:
- name: Checkout bgfx
uses: actions/checkout@v3
with:
path: bgfx
- name: Checkout bx
uses: actions/checkout@v3
with:
repository: bkaradzic/bx
path: bx
- name: Checkout bimg
uses: actions/checkout@v3
with:
repository: bkaradzic/bimg
path: bimg
- name: Prepare
run: |
docker pull emscripten/emsdk
docker run --rm emscripten/emsdk which emcc em++ emar
cd bgfx
EMSCRIPTEN=/emsdk/upstream/emscripten ../bx/tools/bin/linux/genie --with-examples --gcc=wasm gmake
- name: Build
run: >
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/bgfx emscripten/emsdk
make -C /bgfx/bgfx wasm-${{ matrix.config }} -j$(nproc) EMSCRIPTEN=/emsdk/upstream/emscripten
- name: Check
run: |
cd bgfx
ls -lash ".build/wasm/bin"
osx:
strategy:
fail-fast: true

278
3rdparty/cgltf/cgltf.h vendored
View File

@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
* Version: 1.13
* Version: 1.14
*
* Website: https://github.com/jkuhlmann/cgltf
*
@ -63,9 +63,14 @@
* By passing null for the output pointer, users can find out how many floats are required in the
* output buffer.
*
* `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that
* `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can
* find out how many indices are required in the output buffer. Returns 0 if the accessor is
* sparse or if the output component size is less than the accessor's component size.
*
* `cgltf_num_components` is a tiny utility that tells you the dimensionality of
* a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate
* the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
* the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
* similar purposes.
*
* `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to
@ -75,7 +80,7 @@
*
* `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading
* vector types and does not support matrix types. The passed-in element size is the number of uints
* in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in
* in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in
* element_size is too small, or if the accessor is sparse.
*
* `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t
@ -197,6 +202,7 @@ typedef enum cgltf_type
typedef enum cgltf_primitive_type
{
cgltf_primitive_type_invalid,
cgltf_primitive_type_points,
cgltf_primitive_type_lines,
cgltf_primitive_type_line_loop,
@ -389,6 +395,8 @@ typedef struct cgltf_texture
cgltf_sampler* sampler;
cgltf_bool has_basisu;
cgltf_image* basisu_image;
cgltf_bool has_webp;
cgltf_image* webp_image;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
@ -499,6 +507,11 @@ typedef struct cgltf_anisotropy
cgltf_texture_view anisotropy_texture;
} cgltf_anisotropy;
typedef struct cgltf_dispersion
{
cgltf_float dispersion;
} cgltf_dispersion;
typedef struct cgltf_material
{
char* name;
@ -513,6 +526,7 @@ typedef struct cgltf_material
cgltf_bool has_emissive_strength;
cgltf_bool has_iridescence;
cgltf_bool has_anisotropy;
cgltf_bool has_dispersion;
cgltf_pbr_metallic_roughness pbr_metallic_roughness;
cgltf_pbr_specular_glossiness pbr_specular_glossiness;
cgltf_clearcoat clearcoat;
@ -524,6 +538,7 @@ typedef struct cgltf_material
cgltf_emissive_strength emissive_strength;
cgltf_iridescence iridescence;
cgltf_anisotropy anisotropy;
cgltf_dispersion dispersion;
cgltf_texture_view normal_texture;
cgltf_texture_view occlusion_texture;
cgltf_texture_view emissive_texture;
@ -838,7 +853,7 @@ cgltf_size cgltf_component_size(cgltf_component_type component_type);
cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count);
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count);
/* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */
cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size);
@ -938,8 +953,8 @@ static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t
#ifndef CGLTF_CONSTS
static const cgltf_size GlbHeaderSize = 12;
static const cgltf_size GlbChunkHeaderSize = 8;
#define GlbHeaderSize 12
#define GlbChunkHeaderSize 8
static const uint32_t GlbVersion = 2;
static const uint32_t GlbMagic = 0x46546C67;
static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
@ -1033,7 +1048,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
fclose(file);
return cgltf_result_out_of_memory;
}
cgltf_size read_size = fread(file_data, 1, file_size, file);
fclose(file);
@ -1141,7 +1156,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s
// JSON chunk: length
uint32_t json_length;
memcpy(&json_length, json_chunk, 4);
if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)
if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize)
{
return cgltf_result_data_too_short;
}
@ -1158,7 +1173,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s
const void* bin = NULL;
cgltf_size bin_size = 0;
if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length)
{
// We can read another chunk
const uint8_t* bin_chunk = json_chunk + json_length;
@ -1166,7 +1181,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s
// Bin chunk: length
uint32_t bin_length;
memcpy(&bin_length, bin_chunk, 4);
if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)
if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize)
{
return cgltf_result_data_too_short;
}
@ -1552,6 +1567,9 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_accessor* accessor = &data->accessors[i];
CGLTF_ASSERT_IF(data->accessors[i].component_type == cgltf_component_type_invalid, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(data->accessors[i].type == cgltf_type_invalid, cgltf_result_invalid_gltf);
cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type);
if (accessor->buffer_view)
@ -1565,7 +1583,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_accessor_sparse* sparse = &accessor->sparse;
cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type);
cgltf_size indices_component_size = cgltf_component_size(sparse->indices_component_type);
cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
@ -1631,43 +1649,48 @@ cgltf_result cgltf_validate(cgltf_data* data)
for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].type == cgltf_primitive_type_invalid, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
if (data->meshes[i].primitives[j].attributes_count)
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes_count == 0, cgltf_result_invalid_gltf);
cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
CGLTF_ASSERT_IF(first->count == 0, cgltf_result_invalid_gltf);
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
{
cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
{
for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
}
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
{
for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
}
}
cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
CGLTF_ASSERT_IF(indices &&
indices->component_type != cgltf_component_type_r_8u &&
indices->component_type != cgltf_component_type_r_16u &&
indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(indices &&
indices->component_type != cgltf_component_type_r_8u &&
indices->component_type != cgltf_component_type_r_16u &&
indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(indices && indices->type != cgltf_type_scalar, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(indices && indices->stride != cgltf_component_size(indices->component_type), cgltf_result_invalid_gltf);
if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
}
CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
}
}
}
@ -1676,7 +1699,20 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->nodes[i].weights && data->nodes[i].mesh)
{
CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
}
if (data->nodes[i].has_mesh_gpu_instancing)
{
CGLTF_ASSERT_IF(data->nodes[i].mesh == NULL, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes_count == 0, cgltf_result_invalid_gltf);
cgltf_accessor* first = data->nodes[i].mesh_gpu_instancing.attributes[0].data;
for (cgltf_size k = 0; k < data->nodes[i].mesh_gpu_instancing.attributes_count; ++k)
{
CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
}
}
}
@ -1724,10 +1760,15 @@ cgltf_result cgltf_validate(cgltf_data* data)
cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_invalid_gltf);
}
}
for (cgltf_size i = 0; i < data->variants_count; ++i)
{
CGLTF_ASSERT_IF(!data->variants[i].name, cgltf_result_invalid_gltf);
}
return cgltf_result_success;
}
@ -1902,7 +1943,7 @@ void cgltf_free(cgltf_data* data)
data->memory.free_func(data->memory.user_data, data->materials);
for (cgltf_size i = 0; i < data->images_count; ++i)
for (cgltf_size i = 0; i < data->images_count; ++i)
{
data->memory.free_func(data->memory.user_data, data->images[i].name);
data->memory.free_func(data->memory.user_data, data->images[i].uri);
@ -2550,7 +2591,7 @@ cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const
return (cgltf_size)(object - animation->channels);
}
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count)
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count)
{
if (out == NULL)
{
@ -2558,6 +2599,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u
}
index_count = accessor->count < index_count ? accessor->count : index_count;
cgltf_size index_component_size = cgltf_component_size(accessor->component_type);
if (accessor->is_sparse)
{
@ -2567,6 +2609,10 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u
{
return 0;
}
if (index_component_size > out_component_size)
{
return 0;
}
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
if (element == NULL)
{
@ -2574,18 +2620,29 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u
}
element += accessor->offset;
if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint))
if (index_component_size == out_component_size && accessor->stride == out_component_size)
{
memcpy(out, element, index_count * sizeof(cgltf_uint));
memcpy(out, element, index_count * index_component_size);
return index_count;
}
else
{
cgltf_uint* dest = out;
for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride)
// The component size of the output array is larger than the component size of the index data, so index data will be padded.
switch (out_component_size)
{
case 2:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
*dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type);
((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
case 4:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
default:
break;
}
return index_count;
@ -2596,7 +2653,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u
#define CGLTF_ERROR_LEGACY -3
#define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }
#define CGLTF_CHECK_TOKTYPE_RET(tok_, type_, ret_) if ((tok_).type != (type_)) { return ret_; }
#define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */
#define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
@ -2623,12 +2680,13 @@ static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk)
static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk)
{
CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);
CGLTF_CHECK_TOKTYPE_RET(*tok, JSMN_PRIMITIVE, 0);
char tmp[128];
int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1);
strncpy(tmp, (const char*)json_chunk + tok->start, size);
tmp[size] = 0;
return (cgltf_size)CGLTF_ATOLL(tmp);
long long res = CGLTF_ATOLL(tmp);
return res < 0 ? 0 : (cgltf_size)res;
}
static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk)
@ -2810,6 +2868,11 @@ static void cgltf_parse_attribute_type(const char* name, cgltf_attribute_type* o
if (us && *out_type != cgltf_attribute_type_invalid)
{
*out_index = CGLTF_ATOI(us + 1);
if (*out_index < 0)
{
*out_type = cgltf_attribute_type_invalid;
*out_index = 0;
}
}
}
@ -3142,6 +3205,31 @@ static int cgltf_parse_json_material_mappings(cgltf_options* options, jsmntok_t
return i;
}
static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t const* tok, const uint8_t* json_chunk)
{
int type = cgltf_json_to_int(tok, json_chunk);
switch (type)
{
case 0:
return cgltf_primitive_type_points;
case 1:
return cgltf_primitive_type_lines;
case 2:
return cgltf_primitive_type_line_loop;
case 3:
return cgltf_primitive_type_line_strip;
case 4:
return cgltf_primitive_type_triangles;
case 5:
return cgltf_primitive_type_triangle_strip;
case 6:
return cgltf_primitive_type_triangle_fan;
default:
return cgltf_primitive_type_invalid;
}
}
static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -3158,9 +3246,7 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t
if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
{
++i;
out_prim->type
= (cgltf_primitive_type)
cgltf_json_to_int(tokens+i, json_chunk);
out_prim->type = cgltf_json_to_primitive_type(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
@ -3410,7 +3496,7 @@ static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, cons
if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
{
++i;
out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk);
out_sparse->count = cgltf_json_to_size(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)
@ -3546,8 +3632,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to
else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
{
++i;
out_accessor->count =
cgltf_json_to_int(tokens+i, json_chunk);
out_accessor->count = cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)
@ -3700,7 +3785,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const
out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0)
{
++i;
out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
@ -3769,11 +3854,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt
if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0)
{
++i;
out_pbr->metallic_factor =
out_pbr->metallic_factor =
cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0)
else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0)
{
++i;
out_pbr->roughness_factor =
@ -4234,6 +4319,37 @@ static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const*
return i;
}
static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int size = tokens[i].size;
++i;
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0)
{
++i;
out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -4241,11 +4357,11 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token
int size = tokens[i].size;
++i;
for (int j = 0; j < size; ++j)
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri);
}
@ -4325,7 +4441,7 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
= cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
{
++i;
out_sampler->wrap_t
@ -4375,7 +4491,7 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok
out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk));
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
{
++i;
out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
@ -4437,6 +4553,34 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok
}
}
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_texture_webp") == 0)
{
out_texture->has_webp = 1;
++i;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int num_properties = tokens[i].size;
++i;
for (int t = 0; t < num_properties; ++t)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
{
++i;
out_texture->webp_image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
++i;
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++]));
@ -4627,6 +4771,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_anisotropy = 1;
i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0)
{
out_material->has_dispersion = 1;
i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));
@ -4786,7 +4935,7 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_
else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
{
++i;
out_meshopt_compression->count = cgltf_json_to_int(tokens+i, json_chunk);
out_meshopt_compression->count = cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
@ -6442,6 +6591,7 @@ static int cgltf_fixup_pointers(cgltf_data* data)
{
CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count);
CGLTF_PTRFIXUP(data->textures[i].webp_image, data->images, data->images_count);
CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
}

View File

@ -1,7 +1,7 @@
/**
* cgltf_write - a single-file glTF 2.0 writer written in C99.
*
* Version: 1.13
* Version: 1.14
*
* Website: https://github.com/jkuhlmann/cgltf
*
@ -86,6 +86,8 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
#define CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING (1 << 14)
#define CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE (1 << 15)
#define CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY (1 << 16)
#define CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION (1 << 17)
#define CGLTF_EXTENSION_FLAG_TEXTURE_WEBP (1 << 18)
typedef struct {
char* buffer;
@ -178,8 +180,8 @@ typedef struct {
cgltf_write_line(context, "}"); }
#ifndef CGLTF_CONSTS
static const cgltf_size GlbHeaderSize = 12;
static const cgltf_size GlbChunkHeaderSize = 8;
#define GlbHeaderSize 12
#define GlbChunkHeaderSize 8
static const uint32_t GlbVersion = 2;
static const uint32_t GlbMagic = 0x46546C67;
static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;
@ -358,6 +360,21 @@ static int cgltf_int_from_component_type(cgltf_component_type ctype)
}
}
static int cgltf_int_from_primitive_type(cgltf_primitive_type ctype)
{
switch (ctype)
{
case cgltf_primitive_type_points: return 0;
case cgltf_primitive_type_lines: return 1;
case cgltf_primitive_type_line_loop: return 2;
case cgltf_primitive_type_line_strip: return 3;
case cgltf_primitive_type_triangles: return 4;
case cgltf_primitive_type_triangle_strip: return 5;
case cgltf_primitive_type_triangle_fan: return 6;
default: return -1;
}
}
static const char* cgltf_str_from_alpha_mode(cgltf_alpha_mode alpha_mode)
{
switch (alpha_mode)
@ -453,7 +470,7 @@ static void cgltf_write_asset(cgltf_write_context* context, const cgltf_asset* a
static void cgltf_write_primitive(cgltf_write_context* context, const cgltf_primitive* prim)
{
cgltf_write_intprop(context, "mode", (int) prim->type, 4);
cgltf_write_intprop(context, "mode", cgltf_int_from_primitive_type(prim->type), 4);
CGLTF_WRITE_IDXPROP("indices", prim->indices, context->data->accessors);
CGLTF_WRITE_IDXPROP("material", prim->material, context->data->materials);
cgltf_write_line(context, "\"attributes\": {");
@ -490,7 +507,7 @@ static void cgltf_write_primitive(cgltf_write_context* context, const cgltf_prim
context->extension_flags |= CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION;
if (prim->attributes_count == 0 || prim->indices == 0)
{
context->required_extension_flags |= CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION;
context->required_extension_flags |= CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION;
}
cgltf_write_line(context, "\"KHR_draco_mesh_compression\": {");
@ -644,6 +661,11 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY;
}
if (material->has_dispersion)
{
context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION;
}
if (material->has_pbr_metallic_roughness)
{
const cgltf_pbr_metallic_roughness* params = &material->pbr_metallic_roughness;
@ -659,7 +681,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
cgltf_write_line(context, "}");
}
if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy)
if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy || material->has_dispersion)
{
cgltf_write_line(context, "\"extensions\": {");
if (material->has_clearcoat)
@ -711,7 +733,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
{
cgltf_write_floatarrayprop(context, "attenuationColor", params->attenuation_color, 3);
}
if (params->attenuation_distance < FLT_MAX)
if (params->attenuation_distance < FLT_MAX)
{
cgltf_write_floatprop(context, "attenuationDistance", params->attenuation_distance, FLT_MAX);
}
@ -779,6 +801,13 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
CGLTF_WRITE_TEXTURE_INFO("anisotropyTexture", params->anisotropy_texture);
cgltf_write_line(context, "}");
}
if (material->has_dispersion)
{
cgltf_write_line(context, "\"KHR_materials_dispersion\": {");
const cgltf_dispersion* params = &material->dispersion;
cgltf_write_floatprop(context, "dispersion", params->dispersion, 0.f);
cgltf_write_line(context, "}");
}
cgltf_write_line(context, "}");
}
@ -812,15 +841,23 @@ static void cgltf_write_texture(cgltf_write_context* context, const cgltf_textur
CGLTF_WRITE_IDXPROP("source", texture->image, context->data->images);
CGLTF_WRITE_IDXPROP("sampler", texture->sampler, context->data->samplers);
if (texture->has_basisu)
if (texture->has_basisu || texture->has_webp)
{
cgltf_write_line(context, "\"extensions\": {");
if (texture->has_basisu)
{
context->extension_flags |= CGLTF_EXTENSION_FLAG_TEXTURE_BASISU;
cgltf_write_line(context, "\"KHR_texture_basisu\": {");
CGLTF_WRITE_IDXPROP("source", texture->basisu_image, context->data->images);
cgltf_write_line(context, "}");
}
if (texture->has_webp)
{
context->extension_flags |= CGLTF_EXTENSION_FLAG_TEXTURE_WEBP;
cgltf_write_line(context, "\"EXT_texture_webp\": {");
CGLTF_WRITE_IDXPROP("source", texture->webp_image, context->data->images);
cgltf_write_line(context, "}");
}
cgltf_write_line(context, "}");
}
cgltf_write_extras(context, &texture->extras);
@ -1252,6 +1289,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens
if (extension_flags & CGLTF_EXTENSION_FLAG_TEXTURE_BASISU) {
cgltf_write_stritem(context, "KHR_texture_basisu");
}
if (extension_flags & CGLTF_EXTENSION_FLAG_TEXTURE_WEBP) {
cgltf_write_stritem(context, "EXT_texture_webp");
}
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH) {
cgltf_write_stritem(context, "KHR_materials_emissive_strength");
}
@ -1264,6 +1304,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens
if (extension_flags & CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING) {
cgltf_write_stritem(context, "EXT_mesh_gpu_instancing");
}
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION) {
cgltf_write_stritem(context, "KHR_materials_dispersion");
}
}
cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.90 WIP
// dear imgui, v1.91.1 WIP
// (drawing and font code)
/*
@ -8,6 +8,7 @@ Index of this file:
// [SECTION] STB libraries implementation
// [SECTION] Style functions
// [SECTION] ImDrawList
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
// [SECTION] ImDrawListSplitter
// [SECTION] ImDrawData
// [SECTION] Helpers ShadeVertsXXX functions
@ -64,6 +65,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@ -209,11 +211,13 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -223,6 +227,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); // Prefer using Alpha=1.0 here
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
@ -269,11 +274,13 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -283,6 +290,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_TableBorderLight] = ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f);
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
@ -330,11 +338,13 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.26f, 0.59f, 1.00f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -344,6 +354,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_TableBorderLight] = ImVec4(0.68f, 0.68f, 0.74f, 1.00f); // Prefer using Alpha=1.0 here
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.30f, 0.30f, 0.30f, 0.09f);
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
@ -383,12 +394,13 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
}
// Initialize before use in a new frame. We always have a command ready in the buffer.
// In the majority of cases, you would want to call PushClipRect() and PushTextureID() after this.
void ImDrawList::_ResetForNewFrame()
{
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0);
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TextureId) == sizeof(ImVec4));
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
if (_Splitter._Count > 1)
_Splitter.Merge(this);
@ -475,7 +487,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
}
// Compare ClipRect, TextureId and VtxOffset with a single memcmp()
#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
#define ImDrawCmd_HeaderSize (offsetof(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset)
@ -514,7 +526,6 @@ void ImDrawList::_OnChangedClipRect()
CmdBuffer.pop_back();
return;
}
curr_cmd->ClipRect = _CmdHeader.ClipRect;
}
@ -537,7 +548,6 @@ void ImDrawList::_OnChangedTextureID()
CmdBuffer.pop_back();
return;
}
curr_cmd->TextureId = _CmdHeader.TextureId;
}
@ -613,6 +623,15 @@ void ImDrawList::PopTextureID()
_OnChangedTextureID();
}
// This is used by ImGui::PushFont()/PopFont(). It works because we never use _TextureIdStack[] elsewhere than in PushTextureID()/PopTextureID().
void ImDrawList::_SetTextureID(ImTextureID texture_id)
{
if (_CmdHeader.TextureId == texture_id)
return;
_CmdHeader.TextureId = texture_id;
_OnChangedTextureID();
}
// Reserve space for a number of vertices and indices.
// You must finish filling your reserved data before calling PrimReserve() again, as it may reallocate or
// submit the intermediate results. PrimUnreserve() can be used to release unused allocations.
@ -641,7 +660,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
_IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size;
}
// Release the a number of reserved vertices/indices from the end of the last reservation made with PrimReserve().
// Release the number of reserved vertices/indices from the end of the last reservation made with PrimReserve().
void ImDrawList::PrimUnreserve(int idx_count, int vtx_count)
{
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
@ -1217,10 +1236,10 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
}
}
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments)
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments)
{
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
_Path.reserve(_Path.Size + (num_segments + 1));
@ -1229,11 +1248,10 @@ void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float
for (int i = 0; i <= num_segments; i++)
{
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y);
const float rel_x = (point.x * cos_rot) - (point.y * sin_rot);
const float rel_y = (point.x * sin_rot) + (point.y * cos_rot);
point.x = rel_x + center.x;
point.y = rel_y + center.y;
ImVec2 point(ImCos(a) * radius.x, ImSin(a) * radius.y);
const ImVec2 rel((point.x * cos_rot) - (point.y * sin_rot), (point.x * sin_rot) + (point.y * cos_rot));
point.x = rel.x + center.x;
point.y = rel.y + center.y;
_Path.push_back(point);
}
}
@ -1558,31 +1576,31 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
}
// Ellipse
void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness)
void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments, float thickness)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
// Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness);
}
void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments)
void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
// Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
PathFillConvex(col);
}
@ -1613,10 +1631,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
if ((col & IM_COL32_A_MASK) == 0)
return;
// Accept null ranges
if (text_begin == text_end || text_begin[0] == 0)
return;
if (text_end == NULL)
text_end = text_begin + strlen(text_begin);
if (text_begin == text_end)
return;
// Pull default font/size from the shared ImDrawListSharedData instance
if (font == NULL)
@ -1700,6 +1719,316 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi
PopTextureID();
}
//-----------------------------------------------------------------------------
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
//-----------------------------------------------------------------------------
// Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
// Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
// Provided as a convenience for user but not used by main library.
//-----------------------------------------------------------------------------
// - ImTriangulator [Internal]
// - AddConcavePolyFilled()
//-----------------------------------------------------------------------------
enum ImTriangulatorNodeType
{
ImTriangulatorNodeType_Convex,
ImTriangulatorNodeType_Ear,
ImTriangulatorNodeType_Reflex
};
struct ImTriangulatorNode
{
ImTriangulatorNodeType Type;
int Index;
ImVec2 Pos;
ImTriangulatorNode* Next;
ImTriangulatorNode* Prev;
void Unlink() { Next->Prev = Prev; Prev->Next = Next; }
};
struct ImTriangulatorNodeSpan
{
ImTriangulatorNode** Data = NULL;
int Size = 0;
void push_back(ImTriangulatorNode* node) { Data[Size++] = node; }
void find_erase_unsorted(int idx) { for (int i = Size - 1; i >= 0; i--) if (Data[i]->Index == idx) { Data[i] = Data[Size - 1]; Size--; return; } }
};
struct ImTriangulator
{
static int EstimateTriangleCount(int points_count) { return (points_count < 3) ? 0 : points_count - 2; }
static int EstimateScratchBufferSize(int points_count) { return sizeof(ImTriangulatorNode) * points_count + sizeof(ImTriangulatorNode*) * points_count * 2; }
void Init(const ImVec2* points, int points_count, void* scratch_buffer);
void GetNextTriangle(unsigned int out_triangle[3]); // Return relative indexes for next triangle
// Internal functions
void BuildNodes(const ImVec2* points, int points_count);
void BuildReflexes();
void BuildEars();
void FlipNodeList();
bool IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const;
void ReclassifyNode(ImTriangulatorNode* node);
// Internal members
int _TrianglesLeft = 0;
ImTriangulatorNode* _Nodes = NULL;
ImTriangulatorNodeSpan _Ears;
ImTriangulatorNodeSpan _Reflexes;
};
// Distribute storage for nodes, ears and reflexes.
// FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
// (this would require first building reflexes to bail to convex if empty, without even building nodes)
void ImTriangulator::Init(const ImVec2* points, int points_count, void* scratch_buffer)
{
IM_ASSERT(scratch_buffer != NULL && points_count >= 3);
_TrianglesLeft = EstimateTriangleCount(points_count);
_Nodes = (ImTriangulatorNode*)scratch_buffer; // points_count x Node
_Ears.Data = (ImTriangulatorNode**)(_Nodes + points_count); // points_count x Node*
_Reflexes.Data = (ImTriangulatorNode**)(_Nodes + points_count) + points_count; // points_count x Node*
BuildNodes(points, points_count);
BuildReflexes();
BuildEars();
}
void ImTriangulator::BuildNodes(const ImVec2* points, int points_count)
{
for (int i = 0; i < points_count; i++)
{
_Nodes[i].Type = ImTriangulatorNodeType_Convex;
_Nodes[i].Index = i;
_Nodes[i].Pos = points[i];
_Nodes[i].Next = _Nodes + i + 1;
_Nodes[i].Prev = _Nodes + i - 1;
}
_Nodes[0].Prev = _Nodes + points_count - 1;
_Nodes[points_count - 1].Next = _Nodes;
}
void ImTriangulator::BuildReflexes()
{
ImTriangulatorNode* n1 = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
{
if (ImTriangleIsClockwise(n1->Prev->Pos, n1->Pos, n1->Next->Pos))
continue;
n1->Type = ImTriangulatorNodeType_Reflex;
_Reflexes.push_back(n1);
}
}
void ImTriangulator::BuildEars()
{
ImTriangulatorNode* n1 = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
{
if (n1->Type != ImTriangulatorNodeType_Convex)
continue;
if (!IsEar(n1->Prev->Index, n1->Index, n1->Next->Index, n1->Prev->Pos, n1->Pos, n1->Next->Pos))
continue;
n1->Type = ImTriangulatorNodeType_Ear;
_Ears.push_back(n1);
}
}
void ImTriangulator::GetNextTriangle(unsigned int out_triangle[3])
{
if (_Ears.Size == 0)
{
FlipNodeList();
ImTriangulatorNode* node = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, node = node->Next)
node->Type = ImTriangulatorNodeType_Convex;
_Reflexes.Size = 0;
BuildReflexes();
BuildEars();
// If we still don't have ears, it means geometry is degenerated.
if (_Ears.Size == 0)
{
// Return first triangle available, mimicking the behavior of convex fill.
IM_ASSERT(_TrianglesLeft > 0); // Geometry is degenerated
_Ears.Data[0] = _Nodes;
_Ears.Size = 1;
}
}
ImTriangulatorNode* ear = _Ears.Data[--_Ears.Size];
out_triangle[0] = ear->Prev->Index;
out_triangle[1] = ear->Index;
out_triangle[2] = ear->Next->Index;
ear->Unlink();
if (ear == _Nodes)
_Nodes = ear->Next;
ReclassifyNode(ear->Prev);
ReclassifyNode(ear->Next);
_TrianglesLeft--;
}
void ImTriangulator::FlipNodeList()
{
ImTriangulatorNode* prev = _Nodes;
ImTriangulatorNode* temp = _Nodes;
ImTriangulatorNode* current = _Nodes->Next;
prev->Next = prev;
prev->Prev = prev;
while (current != _Nodes)
{
temp = current->Next;
current->Next = prev;
prev->Prev = current;
_Nodes->Next = current;
current->Prev = _Nodes;
prev = current;
current = temp;
}
_Nodes = prev;
}
// A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
bool ImTriangulator::IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const
{
ImTriangulatorNode** p_end = _Reflexes.Data + _Reflexes.Size;
for (ImTriangulatorNode** p = _Reflexes.Data; p < p_end; p++)
{
ImTriangulatorNode* reflex = *p;
if (reflex->Index != i0 && reflex->Index != i1 && reflex->Index != i2)
if (ImTriangleContainsPoint(v0, v1, v2, reflex->Pos))
return false;
}
return true;
}
void ImTriangulator::ReclassifyNode(ImTriangulatorNode* n1)
{
// Classify node
ImTriangulatorNodeType type;
const ImTriangulatorNode* n0 = n1->Prev;
const ImTriangulatorNode* n2 = n1->Next;
if (!ImTriangleIsClockwise(n0->Pos, n1->Pos, n2->Pos))
type = ImTriangulatorNodeType_Reflex;
else if (IsEar(n0->Index, n1->Index, n2->Index, n0->Pos, n1->Pos, n2->Pos))
type = ImTriangulatorNodeType_Ear;
else
type = ImTriangulatorNodeType_Convex;
// Update lists when a type changes
if (type == n1->Type)
return;
if (n1->Type == ImTriangulatorNodeType_Reflex)
_Reflexes.find_erase_unsorted(n1->Index);
else if (n1->Type == ImTriangulatorNodeType_Ear)
_Ears.find_erase_unsorted(n1->Index);
if (type == ImTriangulatorNodeType_Reflex)
_Reflexes.push_back(n1);
else if (type == ImTriangulatorNodeType_Ear)
_Ears.push_back(n1);
n1->Type = type;
}
// Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
// (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
// It is up to caller to ensure not making costly calls that will be outside of visible area.
// As concave fill is noticeably more expensive than other primitives, be mindful of this...
// Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
void ImDrawList::AddConcavePolyFilled(const ImVec2* points, const int points_count, ImU32 col)
{
if (points_count < 3 || (col & IM_COL32_A_MASK) == 0)
return;
const ImVec2 uv = _Data->TexUvWhitePixel;
ImTriangulator triangulator;
unsigned int triangle[3];
if (Flags & ImDrawListFlags_AntiAliasedFill)
{
// Anti-aliased Fill
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
const int idx_count = (points_count - 2) * 3 + points_count * 6;
const int vtx_count = (points_count * 2);
PrimReserve(idx_count, vtx_count);
// Add indexes for fill
unsigned int vtx_inner_idx = _VtxCurrentIdx;
unsigned int vtx_outer_idx = _VtxCurrentIdx + 1;
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
while (triangulator._TrianglesLeft > 0)
{
triangulator.GetNextTriangle(triangle);
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (triangle[0] << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (triangle[1] << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (triangle[2] << 1));
_IdxWritePtr += 3;
}
// Compute normals
_Data->TempBuffer.reserve_discard(points_count);
ImVec2* temp_normals = _Data->TempBuffer.Data;
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
{
const ImVec2& p0 = points[i0];
const ImVec2& p1 = points[i1];
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
temp_normals[i0].x = dy;
temp_normals[i0].y = -dx;
}
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
{
// Average normals
const ImVec2& n0 = temp_normals[i0];
const ImVec2& n1 = temp_normals[i1];
float dm_x = (n0.x + n1.x) * 0.5f;
float dm_y = (n0.y + n1.y) * 0.5f;
IM_FIXNORMAL2F(dm_x, dm_y);
dm_x *= AA_SIZE * 0.5f;
dm_y *= AA_SIZE * 0.5f;
// Add vertices
_VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
_VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
_VtxWritePtr += 2;
// Add indexes for fringes
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
_IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
_IdxWritePtr += 6;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
else
{
// Non Anti-aliased Fill
const int idx_count = (points_count - 2) * 3;
const int vtx_count = points_count;
PrimReserve(idx_count, vtx_count);
for (int i = 0; i < vtx_count; i++)
{
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
_VtxWritePtr++;
}
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
while (triangulator._TrianglesLeft > 0)
{
triangulator.GetNextTriangle(triangle);
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + triangle[0]); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + triangle[1]); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + triangle[2]);
_IdxWritePtr += 3;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
}
//-----------------------------------------------------------------------------
// [SECTION] ImDrawListSplitter
@ -2009,6 +2338,7 @@ ImFontConfig::ImFontConfig()
OversampleV = 1;
GlyphMaxAdvanceX = FLT_MAX;
RasterizerMultiply = 1.0f;
RasterizerDensity = 1.0f;
EllipsisChar = (ImWchar)-1;
}
@ -2492,8 +2822,9 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
{
// Check for valid range. This may also help detect *some* dangling pointers, because a common
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent.
IM_ASSERT(src_range[0] <= src_range[1]);
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent,
// or to forget to zero-terminate the glyph range array.
IM_ASSERT(src_range[0] <= src_range[1] && "Invalid range: is your glyph range array persistent? it is zero-terminated?");
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
}
dst_tmp.SrcCount++;
@ -2566,7 +2897,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// Convert our ranges in the format stb_truetype wants
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.PackRange.font_size = cfg.SizePixels;
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
@ -2575,7 +2906,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels);
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
{
@ -2671,12 +3002,14 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
const float ascent = ImTrunc(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
const float descent = ImTrunc(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
const float ascent = ImCeil(unscaled_ascent * font_scale);
const float descent = ImFloor(unscaled_descent * font_scale);
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{
// Register glyph
@ -2685,7 +3018,11 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
stbtt_aligned_quad q;
float unused_x = 0.0f, unused_y = 0.0f;
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
float x0 = q.x0 * inv_rasterization_scale + font_off_x;
float y0 = q.y0 * inv_rasterization_scale + font_off_y;
float x1 = q.x1 * inv_rasterization_scale + font_off_x;
float y1 = q.y1 * inv_rasterization_scale + font_off_y;
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
}
}
@ -3761,6 +4098,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{
x = start_x;
y += line_height;
if (y > clip_rect.w)
break; // break out of main loop
word_wrap_eol = NULL;
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
continue;
@ -3990,8 +4329,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
}
else
{
draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL
draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR
draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b); // BL
draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e); // TR
}
if (p1.x > rect.Min.x + rounding)
{
@ -4010,8 +4349,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
}
else
{
draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR
draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR
draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b); // TR
draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e); // BR
}
}
draw_list->PathFillConvex(col);
@ -4198,8 +4537,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
//-----------------------------------------------------------------------------
// ProggyClean.ttf
// Copyright (c) 2004, 2005 Tristan Grimmer
// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
// Download and more information at http://upperbounds.net
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
//-----------------------------------------------------------------------------
// File: 'ProggyClean.ttf' (41208 bytes)
// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.90 WIP
// dear imgui, v1.91.1 WIP
// (tables and columns code)
/*
@ -24,8 +24,9 @@ Index of this file:
*/
// Navigating this file:
// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
//-----------------------------------------------------------------------------
// [SECTION] Commentary
@ -48,7 +49,8 @@ Index of this file:
// - TableUpdateLayout() [Internal] followup to BeginTable(): setup everything: widths, columns positions, clipping rectangles. Automatically called by the FIRST call to TableNextRow() or TableHeadersRow().
// | TableSetupDrawChannels() - setup ImDrawList channels
// | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission
// | TableDrawContextMenu() - draw right-click context menu
// | TableBeginContextMenuPopup()
// | - TableDrawDefaultContextMenu() - draw right-click context menu contents
//-----------------------------------------------------------------------------
// - TableHeadersRow() or TableHeader() user submit a headers row (optional)
// | TableSortSpecsClickColumn() - when left-clicked: alter sort order and sort direction
@ -226,6 +228,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_')
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
@ -317,20 +320,30 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
IM_ASSERT(inner_width >= 0.0f);
// If an outer size is specified ahead we will be able to early out when not visible. Exact clipping criteria may evolve.
// FIXME: coarse clipping because access to table data causes two issues:
// - instance numbers varying/unstable. may not be a direct problem for users, but could make outside access broken or confusing, e.g. TestEngine.
// - can't implement support for ImGuiChildFlags_ResizeY as we need to somehow pull the height data from somewhere. this also needs stable instance numbers.
// The side-effects of accessing table data on coarse clip would be:
// - always reserving the pooled ImGuiTable data ahead for a fully clipped table (minor IMHO). Also the 'outer_window_is_measuring_size' criteria may already be defeating this in some situations.
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
const ImVec2 avail_size = GetContentRegionAvail();
const ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to auto-fitting windows!
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
{
ItemSize(outer_rect);
ItemAdd(outer_rect, id);
return false;
}
// [DEBUG] Debug break requested by user
if (g.DebugBreakInTable == id)
IM_DEBUG_BREAK();
// Acquire storage for the table
ImGuiTable* table = g.Tables.GetOrAddByKey(id);
const ImGuiTableFlags table_last_flags = table->Flags;
// Acquire temporary buffers
const int table_idx = g.Tables.GetIndex(table);
@ -348,6 +361,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Initialize
const int previous_frame_active = table->LastFrameActive;
const int instance_no = (previous_frame_active != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
const ImGuiTableFlags previous_flags = table->Flags;
table->ID = id;
table->Flags = flags;
table->LastFrameActive = g.FrameCount;
@ -394,12 +408,12 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f));
// Reset scroll if we are reactivating it
if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
// Create scrolling region (without border and zero window padding)
ImGuiWindowFlags child_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), false, child_flags);
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags);
table->InnerWindow = g.CurrentWindow;
table->WorkRect = table->InnerWindow->WorkRect;
table->OuterRect = table->InnerWindow->Rect();
@ -423,6 +437,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// For non-scrolling tables, WorkRect == OuterRect == InnerRect.
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
}
// Push a standardized ID for both child-using and not-child-using tables
@ -445,16 +460,27 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
// Make left and top borders not overlap our contents by offsetting HostClipRect (#6765)
// Make borders not overlap our contents by offsetting HostClipRect (#6765, #7428, #3752)
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
if (inner_window != outer_window)
{
// FIXME: Because inner_window's Scrollbar doesn't know about border size, since it's not encoded in window->WindowBorderSize,
// it already overlaps it and doesn't need an extra offset. Ideally we should be able to pass custom border size with
// different x/y values to BeginChild().
if (flags & ImGuiTableFlags_BordersOuterV)
{
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
if (inner_window->DecoOuterSizeX2 == 0.0f)
table->HostClipRect.Max.x = ImMax(table->HostClipRect.Max.x - TABLE_BORDER_SIZE, table->HostClipRect.Min.x);
}
if (flags & ImGuiTableFlags_BordersOuterH)
{
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
if (inner_window->DecoOuterSizeY2 == 0.0f)
table->HostClipRect.Max.y = ImMax(table->HostClipRect.Max.y - TABLE_BORDER_SIZE, table->HostClipRect.Min.y);
}
}
// Padding and Spacing
@ -482,7 +508,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
table->InnerClipRect.ClipWithFull(table->HostClipRect);
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : table->HostClipRect.Max.y;
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
@ -493,7 +519,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->DeclColumnsCount = table->AngledHeadersCount = 0;
if (previous_frame_active + 1 < g.FrameCount)
table->IsActiveIdInTable = false;
temp_data->AngledheadersExtraWidth = 0.0f;
table->AngledHeadersHeight = 0.0f;
temp_data->AngledHeadersExtraWidth = 0.0f;
// Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders()
table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong);
@ -506,7 +533,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
inner_window->DC.CurrentTableIdx = table_idx;
if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0)
if ((previous_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0)
table->IsResetDisplayOrderRequest = true;
// Mark as used to avoid GC
@ -1061,6 +1088,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column.
// - ClipRect.Max.x: using MaxX makes it easier for header to receive hover highlight with no discontinuity and display sorting arrow.
// - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter.
const float previous_instance_work_min_x = column->WorkMinX;
column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1;
column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max
column->ItemWidth = ImTrunc(column->WidthGiven * 0.65f);
@ -1113,8 +1141,22 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// column->WorkMinX = ImLerp(column->WorkMinX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f);
// Reset content width variables
column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX;
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX;
if (table->InstanceCurrent == 0)
{
column->ContentMaxXFrozen = column->WorkMinX;
column->ContentMaxXUnfrozen = column->WorkMinX;
column->ContentMaxXHeadersUsed = column->WorkMinX;
column->ContentMaxXHeadersIdeal = column->WorkMinX;
}
else
{
// As we store an absolute value to make per-cell updates faster, we need to offset values used for width computation.
const float offset_from_previous_instance = column->WorkMinX - previous_instance_work_min_x;
column->ContentMaxXFrozen += offset_from_previous_instance;
column->ContentMaxXUnfrozen += offset_from_previous_instance;
column->ContentMaxXHeadersUsed += offset_from_previous_instance;
column->ContentMaxXHeadersIdeal += offset_from_previous_instance;
}
// Don't decrement auto-fit counters until container window got a chance to submit its items
if (table->HostSkipItems == false)
@ -1190,10 +1232,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (g.ActiveId == 0 || (table->IsActiveIdInTable || g.DragDropActive))
table->HighlightColumnHeader = table->HoveredColumnBody;
// [Part 11] Context menu
if (TableBeginContextMenuPopup(table))
// [Part 11] Default context menu
// - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup().
// - To modify or replace this: set table->IsContextPopupNoDefaultContents = true, then call TableBeginContextMenuPopup()/.../EndPopup().
// - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu,
// e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options.
if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table))
{
TableDrawContextMenu(table);
TableDrawDefaultContextMenu(table, table->Flags);
EndPopup();
}
@ -1214,7 +1260,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (table->Flags & ImGuiTableFlags_NoClip)
table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
else
inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false);
inner_window->DrawList->PushClipRect(inner_window->InnerClipRect.Min, inner_window->InnerClipRect.Max, false);
}
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
@ -1229,9 +1275,9 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
// really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height).
// Actual columns highlight/render will be performed in EndTable() and not be affected.
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS;
const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale);
const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight;
const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight);
const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight);
const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight;
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
@ -1335,7 +1381,7 @@ void ImGui::EndTable()
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border);
if (table->ResizedColumn != -1)
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
table->InnerWindow->DC.CursorMaxPos.x = max_pos_x + table->TempData->AngledheadersExtraWidth;
table->InnerWindow->DC.CursorMaxPos.x = max_pos_x + table->TempData->AngledHeadersExtraWidth;
}
// Pop clipping rect
@ -1406,7 +1452,7 @@ void ImGui::EndTable()
if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted)
{
ImGuiTableColumn* column = &table->Columns[table->ResizedColumn];
const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS);
const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale));
const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f);
table->ResizedColumnNextWidth = new_width;
}
@ -1435,7 +1481,10 @@ void ImGui::EndTable()
// CursorPosPrevLine and CursorMaxPos manually. That should be a more general layout feature, see same problem e.g. #3414)
if (inner_window != outer_window)
{
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
EndChild();
inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask;
}
else
{
@ -1453,9 +1502,13 @@ void ImGui::EndTable()
}
else if (temp_data->UserOuterSize.x <= 0.0f)
{
const float decoration_size = table->TempData->AngledheadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f);
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
// Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block
// - Checking for ImGuiTableFlags_ScrollX/ScrollY flag makes us a frame ahead when disabling those flags.
// - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback.
const float inner_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; // Slightly misleading name but used for code symmetry with inner_content_max_y
const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.x : 0.0f);
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, inner_content_max_x + decoration_size - temp_data->UserOuterSize.x);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x + decoration_size));
}
else
{
@ -1463,9 +1516,9 @@ void ImGui::EndTable()
}
if (temp_data->UserOuterSize.y <= 0.0f)
{
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.y : 0.0f;
outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y);
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y + decoration_size));
}
else
{
@ -1558,6 +1611,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
}
// Store name (append with zero-terminator in contiguous buffer)
// FIXME: If we recorded the number of \n in names we could compute header row height
column->NameOffset = -1;
if (label != NULL && label[0] != 0)
{
@ -1880,7 +1934,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (is_visible)
{
// Update data for TableGetHoveredRow()
if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2)
if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2 && table_instance->HoveredRowNext < 0)
table_instance->HoveredRowNext = table->CurrentRow;
// Decide of background color for the row
@ -1935,7 +1989,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
cell_bg_rect.ClipWith(table->BgClipRect);
cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling
cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX);
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
if (cell_bg_rect.Min.y < cell_bg_rect.Max.y)
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
}
}
@ -1952,34 +2007,37 @@ void ImGui::TableEndRow(ImGuiTable* table)
// We need to do that in TableEndRow() instead of TableBeginRow() so the list clipper can mark end of row and
// get the new cursor position.
if (unfreeze_rows_request)
{
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
if (unfreeze_rows_actual)
{
IM_ASSERT(table->IsUnfrozenRows == false);
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
table->IsUnfrozenRows = true;
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y);
float row_height = table->RowPosY2 - table->RowPosY1;
table->RowPosY2 = window->DC.CursorPos.y = table->WorkRect.Min.y + table->RowPosY2 - table->OuterRect.Min.y;
table->RowPosY1 = table->RowPosY2 - row_height;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
if (unfreeze_rows_actual)
{
ImGuiTableColumn* column = &table->Columns[column_n];
column->DrawChannelCurrent = column->DrawChannelUnfrozen;
column->ClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y;
}
IM_ASSERT(table->IsUnfrozenRows == false);
table->IsUnfrozenRows = true;
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y);
float row_height = table->RowPosY2 - table->RowPosY1;
table->RowPosY2 = window->DC.CursorPos.y = table->WorkRect.Min.y + table->RowPosY2 - table->OuterRect.Min.y;
table->RowPosY1 = table->RowPosY2 - row_height;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{
ImGuiTableColumn* column = &table->Columns[column_n];
column->DrawChannelCurrent = column->DrawChannelUnfrozen;
column->ClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y;
}
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
}
}
if (!(table->RowFlags & ImGuiTableRowFlags_Headers))
@ -2145,6 +2203,8 @@ void ImGui::TableEndCell(ImGuiTable* table)
// - TableSetColumnWidthAutoAll() [Internal]
// - TableUpdateColumnsWeightFromWidth() [Internal]
//-------------------------------------------------------------------------
// Note that actual columns widths are computed in TableUpdateLayout().
//-------------------------------------------------------------------------
// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis.
float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
@ -2694,7 +2754,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
const ImU32 outer_col = table->BorderColorStrong;
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
{
inner_drawlist->AddRect(outer_border.Min, outer_border.Max + ImVec2(1, 1), outer_col, 0.0f, 0, border_size);
inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size);
}
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
{
@ -2754,7 +2814,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
static inline ImGuiSortDirection TableGetColumnAvailSortDirection(ImGuiTableColumn* column, int n)
{
IM_ASSERT(n < column->SortDirectionsAvailCount);
return (column->SortDirectionsAvailList >> (n << 1)) & 0x03;
return (ImGuiSortDirection)((column->SortDirectionsAvailList >> (n << 1)) & 0x03);
}
// Fix sort direction if currently set on a value which is unavailable (e.g. activating NoSortAscending/NoSortDescending)
@ -2895,6 +2955,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
}
// Write output
// May be able to move all SortSpecs data from table (48 bytes) to ImGuiTableTempData if we decide to write it back on every BeginTable()
ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data;
if (dirty && sort_specs != NULL)
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
@ -2907,7 +2968,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
sort_spec->ColumnUserID = column->UserID;
sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
sort_spec->SortDirection = column->SortDirection;
sort_spec->SortDirection = (ImGuiSortDirection)column->SortDirection;
}
table->SortSpecs.Specs = sort_specs;
@ -2918,6 +2979,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
// [SECTION] Tables: Headers
//-------------------------------------------------------------------------
// - TableGetHeaderRowHeight() [Internal]
// - TableGetHeaderAngledMaxLabelWidth() [Internal]
// - TableHeadersRow()
// - TableHeader()
// - TableAngledHeadersRow()
@ -2949,12 +3011,12 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth()
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
if (table->Columns[column_n].Flags & ImGuiTableColumnFlags_AngledHeader)
width = ImMax(width, CalcTextSize(TableGetColumnName(table, column_n), NULL, true).x);
return width + g.Style.CellPadding.x * 2.0f;
return width + g.Style.CellPadding.y * 2.0f; // Swap padding
}
// [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn().
// The intent is that advanced users willing to create customized headers would not need to use this helper
// and can create their own! For example: TableHeader() may be preceeded by Checkbox() or other custom widgets.
// and can create their own! For example: TableHeader() may be preceded by Checkbox() or other custom widgets.
// See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this.
// This code is constructed to not make much use of internal functions, as it is intended to be a template to copy.
// FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public.
@ -3073,7 +3135,7 @@ void ImGui::TableHeader(const char* label)
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
}
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding);
if (held)
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
@ -3140,15 +3202,43 @@ void ImGui::TableHeader(const char* label)
}
// Unlike TableHeadersRow() it is not expected that you can reimplement or customize this with custom widgets.
// FIXME: highlight without ImGuiTableFlags_HighlightHoveredColumn
// FIXME: No hit-testing/button on the angled header.
void ImGui::TableAngledHeadersRow()
{
ImGuiContext& g = *GImGui;
TableAngledHeadersRowEx(g.Style.TableAngledHeadersAngle, 0.0f);
ImGuiTable* table = g.CurrentTable;
ImGuiTableTempData* temp_data = table->TempData;
temp_data->AngledHeadersRequests.resize(0);
temp_data->AngledHeadersRequests.reserve(table->ColumnsEnabledCount);
// Which column needs highlight?
const ImGuiID row_id = GetID("##AngledHeaders");
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
int highlight_column_n = table->HighlightColumnHeader;
if (highlight_column_n == -1 && table->HoveredColumnBody != -1)
if (table_instance->HoveredRowLast == 0 && table->HoveredColumnBorder == -1 && (g.ActiveId == 0 || g.ActiveId == row_id || (table->IsActiveIdInTable || g.DragDropActive)))
highlight_column_n = table->HoveredColumnBody;
// Build up request
ImU32 col_header_bg = GetColorU32(ImGuiCol_TableHeaderBg);
ImU32 col_text = GetColorU32(ImGuiCol_Text);
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
{
const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n];
if ((column->Flags & ImGuiTableColumnFlags_AngledHeader) == 0) // Note: can't rely on ImGuiTableColumnFlags_IsVisible test here.
continue;
ImGuiTableHeaderData request = { (ImGuiTableColumnIdx)column_n, col_text, col_header_bg, (column_n == highlight_column_n) ? GetColorU32(ImGuiCol_Header) : 0 };
temp_data->AngledHeadersRequests.push_back(request);
}
// Render row
TableAngledHeadersRowEx(row_id, g.Style.TableAngledHeadersAngle, 0.0f, temp_data->AngledHeadersRequests.Data, temp_data->AngledHeadersRequests.Size);
}
void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
// Important: data must be fed left to right
void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
@ -3171,45 +3261,41 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
// Calculate our base metrics and set angled headers data _before_ the first call to TableNextRow()
// FIXME-STYLE: Would it be better for user to submit 'max_label_width' or 'row_height' ? One can be derived from the other.
const float header_height = table->RowCellPaddingY * 2.0f + g.FontSize;
const float row_height = ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y);
const ImVec2 header_angled_vector = unit_right * (row_height / -sin_a);
const float header_height = g.FontSize + g.Style.CellPadding.x * 2.0f;
const float row_height = ImTrunc(ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y));
table->AngledHeadersHeight = row_height;
table->AngledHeadersSlope = (sin_a != 0.0f) ? (cos_a / sin_a) : 0.0f;
const ImVec2 header_angled_vector = unit_right * (row_height / -sin_a); // vector from bottom-left to top-left, and from bottom-right to top-right
// Declare row, override and draw our own background
TableNextRow(ImGuiTableRowFlags_Headers, row_height);
TableNextColumn();
const ImRect row_r(table->WorkRect.Min.x, table->BgClipRect.Min.y, table->WorkRect.Max.x, table->RowPosY2);
table->DrawSplitter->SetCurrentChannel(draw_list, TABLE_DRAW_CHANNEL_BG0);
float clip_rect_min_x = table->BgClipRect.Min.x;
if (table->FreezeColumnsCount > 0)
clip_rect_min_x = ImMax(clip_rect_min_x, table->Columns[table->FreezeColumnsCount - 1].MaxX);
TableSetBgColor(ImGuiTableBgTarget_RowBg0, 0); // Cancel
PushClipRect(table->BgClipRect.Min, table->BgClipRect.Max, false); // Span all columns
draw_list->AddRectFilled(table->BgClipRect.Min, table->BgClipRect.Max, GetColorU32(ImGuiCol_TableHeaderBg, 0.25f)); // FIXME-STYLE: Change row background with an arbitrary color.
draw_list->AddRectFilled(ImVec2(table->BgClipRect.Min.x, row_r.Min.y), ImVec2(table->BgClipRect.Max.x, row_r.Max.y), GetColorU32(ImGuiCol_TableHeaderBg, 0.25f)); // FIXME-STYLE: Change row background with an arbitrary color.
PushClipRect(ImVec2(clip_rect_min_x, table->BgClipRect.Min.y), table->BgClipRect.Max, true); // Span all columns
const ImRect row_r(table->WorkRect.Min.x, table->BgClipRect.Min.y, table->WorkRect.Max.x, window->DC.CursorPos.y + row_height);
const ImGuiID row_id = GetID("##AngledHeaders");
ButtonBehavior(row_r, row_id, NULL, NULL);
KeepAliveID(row_id);
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
int highlight_column_n = table->HighlightColumnHeader;
if (highlight_column_n == -1 && table->HoveredColumnBody != -1)
if (table_instance->HoveredRowLast == 0 && table->HoveredColumnBorder == -1 && (g.ActiveId == 0 || g.ActiveId == row_id || (table->IsActiveIdInTable || g.DragDropActive)))
highlight_column_n = table->HoveredColumnBody;
const float ascent_scaled = g.Font->Ascent * g.FontScale; // FIXME: Standardize those scaling factors better
const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f);
const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
// Draw background and labels in first pass, then all borders.
float max_x = 0.0f;
for (int pass = 0; pass < 2; pass++)
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
for (int order_n = 0; order_n < data_count; order_n++)
{
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
continue;
const int column_n = table->DisplayOrderToIndex[order_n];
const ImGuiTableHeaderData* request = &data[order_n];
const int column_n = request->Index;
ImGuiTableColumn* column = &table->Columns[column_n];
if ((column->Flags & ImGuiTableColumnFlags_AngledHeader) == 0) // Note: can't rely on ImGuiTableColumnFlags_IsVisible test here.
continue;
ImVec2 bg_shape[4];
bg_shape[0] = ImVec2(column->MaxX, row_r.Max.y);
@ -3219,28 +3305,60 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
if (pass == 0)
{
// Draw shape
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableHeaderBg));
if (column_n == highlight_column_n)
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_Header)); // Highlight on hover
//draw_list->AddQuad(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableBorderLight), 1.0f);
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], request->BgColor0);
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], request->BgColor1); // Optional highlight
max_x = ImMax(max_x, bg_shape[3].x);
// Draw label (first draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset)
// FIXME: May be worth tidying up all those operations to make them easier to understand.
// Draw label
// - First draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset.
// - Handle multiple lines manually, as we want each lines to follow on the horizontal border, rather than see a whole block rotated.
const char* label_name = TableGetColumnName(table, column_n);
const float clip_width = max_label_width - (sin_a * table->RowCellPaddingY);
ImRect label_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width + (flip_label ? 0.0f : table->CellPaddingX), header_height + table->RowCellPaddingY));
ImVec2 label_size = CalcTextSize(label_name, NULL, true);
ImVec2 label_off = ImVec2(flip_label ? ImMax(0.0f, max_label_width - label_size.x - table->CellPaddingX) : table->CellPaddingX, table->RowCellPaddingY);
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
RenderTextEllipsis(draw_list, label_r.Min + label_off, label_r.Max, label_r.Max.x, label_r.Max.x, label_name, NULL, &label_size);
//if (g.IO.KeyShift) { draw_list->AddRect(label_r.Min, label_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f); }
int vtx_idx_end = draw_list->_VtxCurrentIdx;
const char* label_name_end = FindRenderedTextEnd(label_name);
const float line_off_step_x = (g.FontSize / -sin_a);
const int label_lines = ImTextCountLines(label_name, label_name_end);
// Rotate and offset label
ImVec2 pivot_in = label_r.GetBL();
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y) + (flip_label ? (unit_right * clip_width) : ImVec2(header_height, 0.0f));
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
// Left<>Right alignment
float line_off_curr_x = flip_label ? (label_lines - 1) * line_off_step_x : 0.0f;
float line_off_for_align_x = ImMax((((column->MaxX - column->MinX) - padding.x * 2.0f) - (label_lines * line_off_step_x)), 0.0f) * align.x;
line_off_curr_x += line_off_for_align_x - line_off_for_ascent_x;
// Register header width
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(label_lines * line_off_step_x - line_off_for_align_x);
while (label_name < label_name_end)
{
const char* label_name_eol = strchr(label_name, '\n');
if (label_name_eol == NULL)
label_name_eol = label_name_end;
// FIXME: Individual line clipping for right-most column is broken for negative angles.
ImVec2 label_size = CalcTextSize(label_name, label_name_eol);
float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symmetrical but hide more text.
float clip_height = ImMin(label_size.y, column->ClipRect.Max.x - column->WorkMinX - line_off_curr_x);
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
PushStyleColor(ImGuiCol_Text, request->TextColor);
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size);
PopStyleColor();
int vtx_idx_end = draw_list->_VtxCurrentIdx;
// Up<>Down alignment
const float available_space = ImMax(clip_width - label_size.x + ImAbs(padding.x * cos_a) * 2.0f - ImAbs(padding.y * sin_a) * 2.0f, 0.0f);
const float vertical_offset = available_space * align.y * (flip_label ? -1.0f : 1.0f);
// Rotate and offset label
ImVec2 pivot_in = ImVec2(window->ClipRect.Min.x - vertical_offset, window->ClipRect.Min.y + label_size.y);
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y);
line_off_curr_x += flip_label ? -line_off_step_x : line_off_step_x;
pivot_out += unit_right * padding.y;
if (flip_label)
pivot_out += unit_right * (clip_width - ImMax(0.0f, clip_width - label_size.x));
pivot_out.x += flip_label ? line_off_curr_x + line_off_step_x : line_off_curr_x;
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
//if (g.IO.KeyShift) { ImDrawList* fg_dl = GetForegroundDrawList(); vtx_idx_begin = fg_dl->_VtxCurrentIdx; fg_dl->AddRect(clip_r.Min, clip_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 1.0f); ShadeVertsTransformPos(fg_dl, vtx_idx_begin, fg_dl->_VtxCurrentIdx, pivot_in, label_cos_a, label_sin_a, pivot_out); }
label_name = label_name_eol + 1;
}
}
if (pass == 1)
{
@ -3250,14 +3368,15 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
}
PopClipRect();
PopClipRect();
table->TempData->AngledheadersExtraWidth = ImMax(0.0f, max_x - table->Columns[table->RightMostEnabledColumn].MaxX);
table->TempData->AngledHeadersExtraWidth = ImMax(0.0f, max_x - table->Columns[table->RightMostEnabledColumn].MaxX);
}
//-------------------------------------------------------------------------
// [SECTION] Tables: Context Menu
//-------------------------------------------------------------------------
// - TableOpenContextMenu() [Internal]
// - TableDrawContextMenu() [Internal]
// - TableBeginContextMenuPopup() [Internal]
// - TableDrawDefaultContextMenu() [Internal]
//-------------------------------------------------------------------------
// Use -1 to open menu not specific to a given column.
@ -3293,7 +3412,13 @@ bool ImGui::TableBeginContextMenuPopup(ImGuiTable* table)
// Output context menu into current window (generally a popup)
// FIXME-TABLE: Ideally this should be writable by the user. Full programmatic access to that data?
void ImGui::TableDrawContextMenu(ImGuiTable* table)
// Sections to display are pulled from 'flags_for_section_to_display', which is typically == table->Flags.
// - ImGuiTableFlags_Resizable -> display Sizing menu items
// - ImGuiTableFlags_Reorderable -> display "Reset Order"
////- ImGuiTableFlags_Sortable -> display sorting options (disabled)
// - ImGuiTableFlags_Hideable -> display columns visibility menu items
// It means if you have a custom context menus you can call this section and omit some sections, and add your own.
void ImGui::TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags_for_section_to_display)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
@ -3305,7 +3430,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
ImGuiTableColumn* column = (column_n != -1) ? &table->Columns[column_n] : NULL;
// Sizing
if (table->Flags & ImGuiTableFlags_Resizable)
if (flags_for_section_to_display & ImGuiTableFlags_Resizable)
{
if (column != NULL)
{
@ -3325,7 +3450,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
}
// Ordering
if (table->Flags & ImGuiTableFlags_Reorderable)
if (flags_for_section_to_display & ImGuiTableFlags_Reorderable)
{
if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder))
table->IsResetDisplayOrderRequest = true;
@ -3339,7 +3464,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
// Sorting
// (modify TableOpenContextMenu() to add _Sortable flag if enabling this)
#if 0
if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0)
if ((flags_for_section_to_display & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0)
{
if (want_separator)
Separator();
@ -3354,13 +3479,13 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
#endif
// Hiding / Visibility
if (table->Flags & ImGuiTableFlags_Hideable)
if (flags_for_section_to_display & ImGuiTableFlags_Hideable)
{
if (want_separator)
Separator();
want_separator = true;
PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
PushItemFlag(ImGuiItemFlags_AutoClosePopups, false);
for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++)
{
ImGuiTableColumn* other_column = &table->Columns[other_column_n];
@ -3790,7 +3915,8 @@ static const char* DebugNodeTableGetSizingPolicyDesc(ImGuiTableFlags sizing_poli
void ImGui::DebugNodeTable(ImGuiTable* table)
{
const bool is_active = (table->LastFrameActive >= GetFrameCount() - 2); // Note that fully clipped early out scrolling tables will appear as inactive here.
ImGuiContext& g = *GImGui;
const bool is_active = (table->LastFrameActive >= g.FrameCount - 2); // Note that fully clipped early out scrolling tables will appear as inactive here.
if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); }
bool open = TreeNode(table, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*");
if (!is_active) { PopStyleColor(); }
@ -3802,6 +3928,13 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
return;
if (table->InstanceCurrent > 0)
Text("** %d instances of same table! Some data below will refer to last instance.", table->InstanceCurrent + 1);
if (g.IO.ConfigDebugIsDebuggerPresent)
{
if (DebugBreakButton("**DebugBreak**", "in BeginTable()"))
g.DebugBreakInTable = table->ID;
SameLine();
}
bool clear_settings = SmallButton("Clear settings");
BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f) Sizing: '%s'", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight(), DebugNodeTableGetSizingPolicyDesc(table->Flags));
BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsGivenWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "");
@ -3938,7 +4071,7 @@ float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offse
return offset / (columns->OffMaxX - columns->OffMinX);
}
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f;
static const float COLUMNS_HIT_RECT_HALF_THICKNESS = 4.0f;
static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index)
{
@ -3949,7 +4082,7 @@ static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index)
IM_ASSERT(column_index > 0); // We are not supposed to drag column 0.
IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index));
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x;
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale) - window->Pos.x;
x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing);
if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths))
x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing);
@ -4264,7 +4397,7 @@ void ImGui::EndColumns()
ImGuiOldColumnData* column = &columns->Columns[n];
float x = window->Pos.x + GetColumnOffset(n);
const ImGuiID column_id = columns->ID + ImGuiID(n);
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale);
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav))
continue;
@ -4306,12 +4439,12 @@ void ImGui::EndColumns()
NavUpdateCurrentWindowIsScrollPushableX();
}
void ImGui::Columns(int columns_count, const char* id, bool border)
void ImGui::Columns(int columns_count, const char* id, bool borders)
{
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1);
ImGuiOldColumnFlags flags = (border ? 0 : ImGuiOldColumnFlags_NoBorder);
ImGuiOldColumnFlags flags = (borders ? 0 : ImGuiOldColumnFlags_NoBorder);
//flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)

View File

@ -48,5 +48,4 @@ namespace ImGui
#include "widgets/file_list.h"
#include "widgets/gizmo.h"
#include "widgets/markdown.h"
#include "widgets/memory_editor.h"
#include "widgets/range_slider.h"

View File

@ -77,5 +77,4 @@ namespace ImGui
#include "widgets/file_list.inl"
#include "widgets/gizmo.inl"
#include "widgets/markdown.inl"
#include "widgets/memory_editor.inl"
#include "widgets/range_slider.inl"

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +0,0 @@
#include <bx/string.h>
#ifdef _MSC_VER
# define snprintf _snprintf
#endif
namespace ImGui
{
// const char* title;
// if (Begin(title, &Open))
// {
// End();
// }
void MemoryEditor::Draw(void* mem_data_void, int mem_size, int base_display_addr)
{
PushFont(Font::Mono);
unsigned char* mem_data = (unsigned char*)mem_data_void;
BeginChild("##scrolling", ImVec2(0, -GetFrameHeight()));
if (ImGui::BeginPopupContextWindow() )
{
ImGui::Checkbox("HexII", &HexII);
ImGui::EndPopup();
}
PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f) );
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f) );
int addr_digits_count = 0;
for (int n = base_display_addr + mem_size - 1; n > 0; n >>= 4)
{
addr_digits_count++;
}
float glyph_width = CalcTextSize("F").x;
float cell_width = glyph_width * 3; // "FF " we include trailing space in the width to easily catch clicks everywhere
float line_height = GetTextLineHeight();
int line_total_count = (int)((mem_size + Rows-1) / Rows);
ImGuiListClipper clipper;
clipper.Begin(line_total_count, line_height);
int visible_start_addr = clipper.DisplayStart * Rows;
int visible_end_addr = clipper.DisplayEnd * Rows;
bool data_next = false;
if (!AllowEdits || DataEditingAddr >= mem_size)
{
DataEditingAddr = -1;
}
int data_editing_addr_backup = DataEditingAddr;
if (DataEditingAddr != -1)
{
if (IsKeyPressed(GetKeyIndex(ImGuiKey_UpArrow)) && DataEditingAddr >= Rows) { DataEditingAddr -= Rows; DataEditingTakeFocus = true; }
else if (IsKeyPressed(GetKeyIndex(ImGuiKey_DownArrow)) && DataEditingAddr < mem_size - Rows) { DataEditingAddr += Rows; DataEditingTakeFocus = true; }
else if (IsKeyPressed(GetKeyIndex(ImGuiKey_LeftArrow)) && DataEditingAddr > 0) { DataEditingAddr -= 1; DataEditingTakeFocus = true; }
else if (IsKeyPressed(GetKeyIndex(ImGuiKey_RightArrow)) && DataEditingAddr < mem_size - 1) { DataEditingAddr += 1; DataEditingTakeFocus = true; }
}
if ((DataEditingAddr / Rows) != (data_editing_addr_backup / Rows))
{
// Track cursor movements
float scroll_offset = ((DataEditingAddr / Rows) - (data_editing_addr_backup / Rows)) * line_height;
bool scroll_desired = (scroll_offset < 0.0f && DataEditingAddr < visible_start_addr + Rows*2) || (scroll_offset > 0.0f && DataEditingAddr > visible_end_addr - Rows*2);
if (scroll_desired)
{
SetScrollY(GetScrollY() + scroll_offset);
}
}
bool draw_separator = true;
for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible items
{
int addr = line_i * Rows;
Text("%0*x: ", addr_digits_count, base_display_addr+addr);
SameLine();
// Draw Hexadecimal
float line_start_x = GetCursorPosX();
for (int n = 0; n < Rows && addr < mem_size; n++, addr++)
{
SameLine(line_start_x + cell_width * n);
if (DataEditingAddr == addr)
{
// Display text input on current byte
PushID(addr);
struct FuncHolder
{
// FIXME: We should have a way to retrieve the text edit cursor position more easily in the API, this is rather tedious.
static int Callback(ImGuiInputTextCallbackData* data)
{
int* p_cursor_pos = (int*)data->UserData;
if (!data->HasSelection())
{
*p_cursor_pos = data->CursorPos;
}
return 0;
}
};
int cursor_pos = -1;
bool data_write = false;
if (DataEditingTakeFocus)
{
SetKeyboardFocusHere();
snprintf(AddrInput, sizeof(AddrInput), "%0*x", addr_digits_count, base_display_addr+addr);
snprintf(DataInput, sizeof(DataInput), "%02x", mem_data[addr]);
}
PushItemWidth(CalcTextSize("FF").x);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CharsHexadecimal|ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_AutoSelectAll|ImGuiInputTextFlags_NoHorizontalScroll|ImGuiInputTextFlags_AlwaysOverwrite|ImGuiInputTextFlags_CallbackAlways;
if (InputText("##data", DataInput, 32, flags, FuncHolder::Callback, &cursor_pos))
{
data_write = data_next = true;
}
else if (!DataEditingTakeFocus && !IsItemActive())
{
DataEditingAddr = -1;
}
DataEditingTakeFocus = false;
PopItemWidth();
if (cursor_pos >= 2)
{
data_write = data_next = true;
}
if (data_write)
{
int data;
if (sscanf(DataInput, "%X", &data) == 1)
{
mem_data[addr] = (unsigned char)data;
}
}
PopID();
}
else
{
if (HexII)
{
unsigned char byte = mem_data[addr];
if (bx::isPrint(byte) )
{
Text(".%c ", byte);
}
else if (0x00 == byte)
{
Text(" ");
}
else if (0xff == byte)
{
Text("## ");
}
else
{
Text("%02x ", byte);
}
}
else
{
Text("%02x ", mem_data[addr]);
}
if (AllowEdits && IsItemHovered() && IsMouseClicked(0))
{
DataEditingTakeFocus = true;
DataEditingAddr = addr;
}
}
}
SameLine(line_start_x + cell_width * Rows + glyph_width * 2);
if (draw_separator)
{
ImVec2 screen_pos = GetCursorScreenPos();
GetWindowDrawList()->AddLine(ImVec2(screen_pos.x - glyph_width, screen_pos.y - 9999), ImVec2(screen_pos.x - glyph_width, screen_pos.y + 9999), ImColor(GetStyle().Colors[ImGuiCol_Border]));
draw_separator = false;
}
// Draw ASCII values
addr = line_i * Rows;
for (int n = 0; n < Rows && addr < mem_size; n++, addr++)
{
if (n > 0) { SameLine(); }
int c = mem_data[addr];
Text("%c", (c >= 32 && c < 128) ? c : '.');
}
}
clipper.End();
PopStyleVar(2);
EndChild();
if (data_next && DataEditingAddr < mem_size)
{
DataEditingAddr = DataEditingAddr + 1;
DataEditingTakeFocus = true;
}
Separator();
AlignTextToFramePadding();
PushItemWidth(50);
PushTabStop(false);
int rows_backup = Rows;
if (DragInt("##rows", &Rows, 0.2f, 4, 32, "%.0f rows"))
{
ImVec2 new_window_size = GetWindowSize();
new_window_size.x += (Rows - rows_backup) * (cell_width + glyph_width);
SetWindowSize(new_window_size);
}
PopTabStop();
PopItemWidth();
SameLine();
Text("Range %0*x..%0*x", addr_digits_count, (int)base_display_addr, addr_digits_count, (int)base_display_addr+mem_size-1);
SameLine();
PushItemWidth(70);
if (InputText("##addr", AddrInput, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue))
{
int goto_addr;
if (sscanf(AddrInput, "%X", &goto_addr) == 1)
{
goto_addr -= base_display_addr;
if (goto_addr >= 0 && goto_addr < mem_size)
{
BeginChild("##scrolling");
SetScrollFromPosY(GetCursorStartPos().y + (goto_addr / Rows) * GetTextLineHeight());
EndChild();
DataEditingAddr = goto_addr;
DataEditingTakeFocus = true;
}
}
}
PopItemWidth();
PopFont();
}
void MemoryEditor::Draw(const void* mem_data, int mem_size, int base_display_addr)
{
Draw(const_cast<void*>(mem_data), mem_size, base_display_addr);
}
} // namespace ImGui

View File

@ -183,13 +183,12 @@ bool RangeSliderFloat(const char* label, float* v1, float* v2, float v_min, floa
// Tabbing or CTRL-clicking on Slider turns it into an input box
bool start_text_input = false;
const bool tab_focus_requested = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
if (hovered && g.IO.MouseClicked[0])
{
SetActiveID(id, window);
FocusWindow(window);
if (tab_focus_requested || g.IO.KeyCtrl)
if (g.IO.KeyCtrl)
{
start_text_input = true;
g.TempInputId = 0;

View File

@ -32,6 +32,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "glslang/Include/glslang_c_interface.h"
#include <cstring>
#include "glslang/Public/ShaderLang.h"
#include "SPIRV/GlslangToSpv.h"
#include "SPIRV/Logger.h"
#include "SPIRV/SpvTools.h"
@ -95,6 +97,8 @@ GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_
const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
program->spirv.clear();
glslang::GlslangToSpv(*intermediate, program->spirv, &logger, reinterpret_cast<glslang::SpvOptions*>(spv_options));
program->loggerMessages = logger.getAllMessages();

View File

@ -41,5 +41,6 @@ static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
static const char* const E_SPV_EXT_shader_tile_image = "SPV_EXT_shader_tile_image";
static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader";
static const char* const E_SPV_ARM_cooperative_matrix_layouts = "SPV_ARM_cooperative_matrix_layouts";
#endif // #ifndef GLSLextEXT_H

View File

@ -1,5 +1,6 @@
/*
** Copyright (c) 2014-2020 The Khronos Group Inc.
** Copyright (C) 2022-2024 Arm Limited.
** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
@ -53,8 +54,14 @@ static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_termi
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
static const char* const E_SPV_KHR_quad_control = "SPV_KHR_quad_control";
static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests";
static const char* const E_SPV_KHR_ray_tracing_position_fetch = "SPV_KHR_ray_tracing_position_fetch";
static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_cooperative_matrix";
static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence";
static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate";
static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume";
static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_replicated_composites";
static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relaxed_extended_instruction";
#endif // #ifndef GLSLextKHR_H

View File

@ -87,4 +87,7 @@ const char* const E_SPV_NV_shader_invocation_reorder = "SPV_NV_shader_invocation
//SPV_NV_displacement_micromap
const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap";
//SPV_NV_shader_atomic_fp16_vector
const char* const E_SPV_NV_shader_atomic_fp16_vector = "SPV_NV_shader_atomic_fp16_vector";
#endif // #ifndef GLSLextNV_H

View File

@ -37,5 +37,7 @@ static const int GLSLextQCOMRevision = 1;
//SPV_QCOM_image_processing
const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing";
//SPV_QCOM_image_processing2
const char* const E_SPV_QCOM_image_processing2 = "SPV_QCOM_image_processing2";
#endif // #ifndef GLSLextQCOM_H

552
3rdparty/glslang/SPIRV/GlslangToSpv.cpp vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -35,19 +35,26 @@
#pragma once
#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning(disable : 4464) // relative include path contains '..'
#endif
#include "SpvTools.h"
#include "glslang/Include/intermediate.h"
#include <string>
#include <vector>
#include "Logger.h"
namespace glslang {
class TIntermediate;
struct SpvOptions {
bool generateDebugInfo {false};
bool stripDebugInfo {false};
bool disableOptimizer {true};
bool optimizeSize {false};
bool disassemble {false};
bool validate {false};
bool emitNonSemanticShaderDebugInfo {false};
bool emitNonSemanticShaderDebugSource{ false };
bool compileOnly{false};
bool optimizerAllowExpandedIDBound{false};
};
void GetSpirvVersion(std::string&);
int GetSpirvGeneratorVersion();

View File

@ -38,7 +38,6 @@
#include <algorithm>
#include <cassert>
#include "../glslang/Include/Common.h"
namespace spv {

View File

@ -77,10 +77,11 @@ public:
#include <cassert>
#include "spirv.hpp"
#include "spvIR.h"
namespace spv {
static inline constexpr Id NoResult = 0;
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
class spirvbin_t : public spirvbin_base_t
{

File diff suppressed because it is too large Load Diff

View File

@ -56,6 +56,7 @@ namespace spv {
}
#include <algorithm>
#include <cstdint>
#include <map>
#include <memory>
#include <set>
@ -103,31 +104,53 @@ public:
stringIds[file_c_str] = strId;
return strId;
}
spv::Id getSourceFile() const
spv::Id getMainFileId() const { return mainFileId; }
// Initialize the main source file name
void setDebugSourceFile(const std::string& file)
{
return sourceFileStringId;
if (trackDebugInfo) {
dirtyLineTracker = true;
mainFileId = getStringId(file);
currentFileId = mainFileId;
}
}
void setSourceFile(const std::string& file)
// Set the debug source location tracker in the builder.
// The upcoming instructions in basic blocks will be associated to this location.
void setDebugSourceLocation(int line, const char* filename)
{
sourceFileStringId = getStringId(file);
currentFileId = sourceFileStringId;
if (trackDebugInfo) {
dirtyLineTracker = true;
if (line != 0) {
// TODO: This is special handling of some AST nodes having (untracked) line 0.
// But they should have a valid line number.
currentLine = line;
if (filename) {
currentFileId = getStringId(filename);
}
}
}
}
void setSourceText(const std::string& text) { sourceText = text; }
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
void setEmitOpLines() { emitOpLines = true; }
void setEmitNonSemanticShaderDebugInfo(bool const emit)
void setEmitSpirvDebugInfo()
{
emitNonSemanticShaderDebugInfo = emit;
if(emit)
{
importNonSemanticShaderDebugInfoInstructions();
}
trackDebugInfo = true;
emitSpirvDebugInfo = true;
}
void setEmitNonSemanticShaderDebugSource(bool const src)
void setEmitNonSemanticShaderDebugInfo(bool emitSourceText)
{
emitNonSemanticShaderDebugSource = src;
trackDebugInfo = true;
emitNonSemanticShaderDebugInfo = true;
importNonSemanticShaderDebugInfoInstructions();
if (emitSourceText) {
emitNonSemanticShaderDebugSource = emitSourceText;
}
}
void addExtension(const char* ext) { extensions.insert(ext); }
void removeExtension(const char* ext)
@ -169,23 +192,9 @@ public:
return id;
}
// Generate OpLine for non-filename-based #line directives (ie no filename
// seen yet): Log the current line, and if different than the last one,
// issue a new OpLine using the new line and current source file name.
void setLine(int line);
// If filename null, generate OpLine for non-filename-based line directives,
// else do filename-based: Log the current line and file, and if different
// than the last one, issue a new OpLine using the new line and file
// name.
void setLine(int line, const char* filename);
// Low-level OpLine. See setLine() for a layered helper.
void addLine(Id fileName, int line, int column);
void addDebugScopeAndLine(Id fileName, int line, int column);
// For creating new types (will return old type if the requested one was already made).
Id makeVoidType();
Id makeBoolType(bool const compilerGenerated = true);
Id makeBoolType();
Id makePointer(StorageClass, Id pointee);
Id makeForwardPointer(StorageClass);
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
@ -226,20 +235,25 @@ public:
Id makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc);
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, char const*const name,
NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType = false);
Id makePointerDebugType(StorageClass storageClass, Id const baseType);
Id makeForwardPointerDebugType(StorageClass storageClass);
Id makeDebugSource(const Id fileName);
Id makeDebugCompilationUnit();
Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
Id makeDebugExpression();
Id makeDebugDeclare(Id const debugLocalVariable, Id const localVariable);
Id makeDebugDeclare(Id const debugLocalVariable, Id const pointer);
Id makeDebugValue(Id const debugLocalVariable, Id const value);
Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
Id makeDebugLexicalBlock(uint32_t line);
std::string unmangleFunctionName(std::string const& name) const;
void setupDebugFunctionEntry(Function* function, const char* name, int line,
const std::vector<Id>& paramTypes,
const std::vector<char const*>& paramNames);
// Initialize non-semantic debug information for a function, including those of:
// - The function definition
// - The function parameters
void setupFunctionDebugInfo(Function* function, const char* name, const std::vector<Id>& paramTypes,
const std::vector<char const*>& paramNames);
// accelerationStructureNV type
Id makeAccelerationStructureType();
@ -254,9 +268,9 @@ public:
Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
Op getMostBasicTypeClass(Id typeId) const;
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
int getNumTypeConstituents(Id typeId) const;
int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
unsigned int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
unsigned int getNumTypeConstituents(Id typeId) const;
unsigned int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
Id getScalarTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const;
@ -317,8 +331,6 @@ public:
// See if a resultId is valid for use as an initializer.
bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
bool isRayTracingOpCode(Op opcode) const;
int getScalarTypeWidth(Id typeId) const
{
Id scalarTypeId = getScalarTypeId(typeId);
@ -326,18 +338,18 @@ public:
return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
}
int getTypeNumColumns(Id typeId) const
unsigned int getTypeNumColumns(Id typeId) const
{
assert(isMatrixType(typeId));
return getNumTypeConstituents(typeId);
}
int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
int getTypeNumRows(Id typeId) const
unsigned int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
unsigned int getTypeNumRows(Id typeId) const
{
assert(isMatrixType(typeId));
return getNumTypeComponents(getContainedTypeId(typeId));
}
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
unsigned int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
Dim getTypeDimensionality(Id typeId) const
{
@ -408,11 +420,16 @@ public:
// Also reset current last DebugScope and current source line to unknown
void setBuildPoint(Block* bp) {
buildPoint = bp;
lastDebugScopeId = NoResult;
currentLine = 0;
// TODO: Technically, change of build point should set line tracker dirty. But we'll have bad line info for
// branch instructions. Commenting this for now because at least this matches the old behavior.
dirtyScopeTracker = true;
}
Block* getBuildPoint() const { return buildPoint; }
// Append an instruction to the end of the current build point.
// Optionally, additional debug info instructions may also be prepended.
void addInstruction(std::unique_ptr<Instruction> inst);
// Make the entry-point function. The returned pointer is only valid
// for the lifetime of this builder.
Function* makeEntryPoint(const char*);
@ -420,20 +437,19 @@ public:
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
LinkageType linkType, const std::vector<Id>& paramTypes,
const std::vector<char const*>& paramNames,
const std::vector<std::vector<Decoration>>& precisions, Block **entry = nullptr);
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
const std::vector<Id>& paramTypes,
const std::vector<std::vector<Decoration>>& precisions, Block** entry = nullptr);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
void makeReturn(bool implicit, Id retVal = 0);
// Initialize state and generate instructions for new lexical scope
void enterScope(uint32_t line);
void enterLexicalBlock(uint32_t line);
// Set state and generate instructions to exit current lexical scope
void leaveScope();
void leaveLexicalBlock();
// Prepare builder for generation of instructions for a function.
void enterFunction(Function const* function);
@ -844,6 +860,8 @@ public:
void postProcess(Instruction&);
// Hook to visit each non-32-bit sized float/int operation in a block.
void postProcessType(const Instruction&, spv::Id typeId);
// move OpSampledImage instructions to be next to their users.
void postProcessSamplers();
void dump(std::vector<unsigned int>&) const;
@ -859,6 +877,8 @@ public:
// Check if the builder is generating code for spec constants.
bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }
void setUseReplicatedComposites(bool use) { useReplicatedComposites = use; }
protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
@ -874,29 +894,48 @@ public:
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void dumpSourceInstructions(std::vector<unsigned int>&) const;
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
template <class Range> void dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const;
void dumpModuleProcesses(std::vector<unsigned int>&) const;
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
const;
struct DecorationInstructionLessThan {
bool operator()(const std::unique_ptr<Instruction>& lhs, const std::unique_ptr<Instruction>& rhs) const;
};
unsigned int spvVersion; // the version of SPIR-V to emit in the header
SourceLanguage sourceLang;
int sourceVersion;
spv::Id sourceFileStringId;
spv::Id nonSemanticShaderCompilationUnitId {0};
spv::Id nonSemanticShaderDebugInfo {0};
spv::Id debugInfoNone {0};
spv::Id debugExpression {0}; // Debug expression with zero operations.
std::string sourceText;
int currentLine;
const char* currentFile;
spv::Id currentFileId;
// True if an new OpLine/OpDebugLine may need to be inserted. Either:
// 1. The current debug location changed
// 2. The current build point changed
bool dirtyLineTracker;
int currentLine = 0;
// OpString id of the current file name. Always 0 if debug info is off.
spv::Id currentFileId = 0;
// OpString id of the main file name. Always 0 if debug info is off.
spv::Id mainFileId = 0;
// True if an new OpDebugScope may need to be inserted. Either:
// 1. A new lexical block is pushed
// 2. The current build point changed
bool dirtyScopeTracker;
std::stack<spv::Id> currentDebugScopeId;
spv::Id lastDebugScopeId;
bool emitOpLines;
bool emitNonSemanticShaderDebugInfo;
bool restoreNonSemanticShaderDebugInfo;
bool emitNonSemanticShaderDebugSource;
// This flag toggles tracking of debug info while building the SPIR-V.
bool trackDebugInfo = false;
// This flag toggles emission of SPIR-V debug instructions, like OpLine and OpSource.
bool emitSpirvDebugInfo = false;
// This flag toggles emission of Non-Semantic Debug extension debug instructions.
bool emitNonSemanticShaderDebugInfo = false;
bool restoreNonSemanticShaderDebugInfo = false;
bool emitNonSemanticShaderDebugSource = false;
std::set<std::string> extensions;
std::vector<const char*> sourceExtensions;
std::vector<const char*> moduleProcesses;
@ -909,6 +948,7 @@ public:
Id uniqueId;
Function* entryPointFunction;
bool generatingOpCodeForSpecConst;
bool useReplicatedComposites { false };
AccessChain accessChain;
// special blocks of instructions for output
@ -917,7 +957,7 @@ public:
std::vector<std::unique_ptr<Instruction> > entryPoints;
std::vector<std::unique_ptr<Instruction> > executionModes;
std::vector<std::unique_ptr<Instruction> > names;
std::vector<std::unique_ptr<Instruction> > decorations;
std::set<std::unique_ptr<Instruction>, DecorationInstructionLessThan> decorations;
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions;

View File

@ -181,6 +181,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
else if (width == 8)
addCapability(CapabilityInt8);
}
break;
default:
if (basicTypeOp == OpTypeInt) {
if (width == 16)
@ -386,12 +387,14 @@ void Builder::postProcessCFG()
}
// Remove unneeded decorations, for unreachable instructions
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
Id decoration_id = I.get()->getIdOperand(0);
return unreachableDefinitions.count(decoration_id) != 0;
}),
decorations.end());
for (auto decorationIter = decorations.begin(); decorationIter != decorations.end();) {
Id decorationId = (*decorationIter)->getIdOperand(0);
if (unreachableDefinitions.count(decorationId) != 0) {
decorationIter = decorations.erase(decorationIter);
} else {
++decorationIter;
}
}
}
// comment in header
@ -482,6 +485,58 @@ void Builder::postProcessFeatures() {
}
}
// SPIR-V requires that any instruction consuming the result of an OpSampledImage
// be in the same block as the OpSampledImage instruction. This pass goes finds
// uses of OpSampledImage where that is not the case and duplicates the
// OpSampledImage to be immediately before the instruction that consumes it.
// The old OpSampledImage is left in place, potentially with no users.
void Builder::postProcessSamplers()
{
// first, find all OpSampledImage instructions and store them in a map.
std::map<Id, Instruction*> sampledImageInstrs;
for (auto f: module.getFunctions()) {
for (auto b: f->getBlocks()) {
for (auto &i: b->getInstructions()) {
if (i->getOpCode() == spv::OpSampledImage) {
sampledImageInstrs[i->getResultId()] = i.get();
}
}
}
}
// next find all uses of the given ids and rewrite them if needed.
for (auto f: module.getFunctions()) {
for (auto b: f->getBlocks()) {
auto &instrs = b->getInstructions();
for (size_t idx = 0; idx < instrs.size(); idx++) {
Instruction *i = instrs[idx].get();
for (int opnum = 0; opnum < i->getNumOperands(); opnum++) {
// Is this operand of the current instruction the result of an OpSampledImage?
if (i->isIdOperand(opnum) &&
sampledImageInstrs.count(i->getIdOperand(opnum)))
{
Instruction *opSampImg = sampledImageInstrs[i->getIdOperand(opnum)];
if (i->getBlock() != opSampImg->getBlock()) {
Instruction *newInstr = new Instruction(getUniqueId(),
opSampImg->getTypeId(),
spv::OpSampledImage);
newInstr->addIdOperand(opSampImg->getIdOperand(0));
newInstr->addIdOperand(opSampImg->getIdOperand(1));
newInstr->setBlock(b);
// rewrite the user of the OpSampledImage to use the new instruction.
i->setIdOperand(opnum, newInstr->getResultId());
// insert the new OpSampledImage right before the current instruction.
instrs.insert(instrs.begin() + idx,
std::unique_ptr<Instruction>(newInstr));
idx++;
}
}
}
}
}
}
}
// comment in header
void Builder::postProcess(bool compileOnly)
{
@ -490,6 +545,7 @@ void Builder::postProcess(bool compileOnly)
postProcessCFG();
postProcessFeatures();
postProcessSamplers();
}
}; // end spv namespace

View File

@ -44,6 +44,7 @@
#include "SpvTools.h"
#include "spirv-tools/optimizer.hpp"
#include "glslang/MachineIndependent/localintermediate.h"
namespace glslang {
@ -218,9 +219,20 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
spvtools::OptimizerOptions spvOptOptions;
if (options->optimizerAllowExpandedIDBound)
spvOptOptions.set_max_id_bound(0x3FFFFFFF);
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
if (options->optimizerAllowExpandedIDBound) {
if (spirv.size() > 3 && spirv[3] > kDefaultMaxIdBound) {
spvtools::Optimizer optimizer2(target_env);
optimizer2.SetMessageConsumer(OptimizerMesssageConsumer);
optimizer2.RegisterPass(spvtools::CreateCompactIdsPass());
optimizer2.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
}
}
}
bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,

View File

@ -44,28 +44,20 @@
#if ENABLE_OPT
#include <vector>
#include <ostream>
#include <unordered_set>
#include "spirv-tools/libspirv.h"
#endif
#include "glslang/MachineIndependent/localintermediate.h"
#include "glslang/MachineIndependent/Versions.h"
#include "GlslangToSpv.h"
#include "Logger.h"
namespace glslang {
struct SpvOptions {
bool generateDebugInfo {false};
bool stripDebugInfo {false};
bool disableOptimizer {true};
bool optimizeSize {false};
bool disassemble {false};
bool validate {false};
bool emitNonSemanticShaderDebugInfo {false};
bool emitNonSemanticShaderDebugSource{ false };
bool compileOnly{false};
};
#if ENABLE_OPT
class TIntermediate;
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);

View File

@ -80,6 +80,7 @@ enum ExtInstSet {
GLSLextNVInst,
OpenCLExtInst,
NonSemanticDebugPrintfExtInst,
NonSemanticDebugBreakExtInst,
NonSemanticShaderDebugInfo100
};
@ -360,7 +361,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
switch (stream[word]) {
case 8: idDescriptor[resultId] = "int8_t"; break;
case 16: idDescriptor[resultId] = "int16_t"; break;
default: assert(0); // fallthrough
default: assert(0); [[fallthrough]];
case 32: idDescriptor[resultId] = "int"; break;
case 64: idDescriptor[resultId] = "int64_t"; break;
}
@ -368,7 +369,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case OpTypeFloat:
switch (stream[word]) {
case 16: idDescriptor[resultId] = "float16_t"; break;
default: assert(0); // fallthrough
default: assert(0); [[fallthrough]];
case 32: idDescriptor[resultId] = "float"; break;
case 64: idDescriptor[resultId] = "float64_t"; break;
}
@ -506,6 +507,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
extInstSet = OpenCLExtInst;
} else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
extInstSet = NonSemanticDebugPrintfExtInst;
} else if (strcmp("NonSemantic.DebugBreak", name) == 0) {
extInstSet = NonSemanticDebugBreakExtInst;
} else if (strcmp("NonSemantic.Shader.DebugInfo.100", name) == 0) {
extInstSet = NonSemanticShaderDebugInfo100;
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
@ -533,6 +536,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
out << "(DebugPrintf)";
} else if (extInstSet == NonSemanticDebugBreakExtInst) {
out << "(DebugBreak)";
} else if (extInstSet == NonSemanticShaderDebugInfo100) {
out << "(" << NonSemanticShaderDebugInfo100GetDebugNames(entrypoint) << ")";
}

87
3rdparty/glslang/SPIRV/doc.cpp vendored Executable file → Normal file
View File

@ -1,5 +1,6 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
// Copyright (C) 2022-2024 Arm Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
@ -198,6 +199,7 @@ const char* ExecutionModeString(int mode)
case ExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD";
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
case ExecutionModeMaximallyReconvergesKHR: return "MaximallyReconverges";
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
@ -217,6 +219,9 @@ const char* ExecutionModeString(int mode)
case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL";
case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL";
case ExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR";
case ExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR";
case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT";
case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT";
case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT";
@ -314,6 +319,7 @@ const char* DecorationString(int decoration)
case DecorationWeightTextureQCOM: return "DecorationWeightTextureQCOM";
case DecorationBlockMatchTextureQCOM: return "DecorationBlockMatchTextureQCOM";
case DecorationBlockMatchSamplerQCOM: return "DecorationBlockMatchSamplerQCOM";
case DecorationExplicitInterpAMD: return "ExplicitInterpAMD";
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
case DecorationPassthroughNV: return "PassthroughNV";
@ -938,6 +944,7 @@ const char* CapabilityString(int info)
case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR";
case CapabilityDrawParameters: return "DrawParameters";
case CapabilitySubgroupVoteKHR: return "SubgroupVoteKHR";
case CapabilityGroupNonUniformRotateKHR: return "CapabilityGroupNonUniformRotateKHR";
case CapabilityStorageUniformBufferBlock16: return "StorageUniformBufferBlock16";
case CapabilityStorageUniform16: return "StorageUniform16";
@ -1028,14 +1035,20 @@ const char* CapabilityString(int info)
case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT";
case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT";
case CapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM";
case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR";
case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT";
case CapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV";
case CapabilityShaderClockKHR: return "ShaderClockKHR";
case CapabilityQuadControlKHR: return "QuadControlKHR";
case CapabilityInt64ImageEXT: return "Int64ImageEXT";
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
case CapabilityExpectAssumeKHR: return "ExpectAssumeKHR";
case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT";
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
@ -1053,6 +1066,9 @@ const char* CapabilityString(int info)
case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM";
case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM";
case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM";
case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM";
case CapabilityReplicatedCompositesEXT: return "CapabilityReplicatedCompositesEXT";
default: return "Bad";
}
@ -1431,11 +1447,18 @@ const char* OpcodeString(int op)
case 4429: return "OpSubgroupAnyKHR";
case 4430: return "OpSubgroupAllEqualKHR";
case 4432: return "OpSubgroupReadInvocationKHR";
case 4433: return "OpExtInstWithForwardRefsKHR";
case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR";
case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR";
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
case OpAssumeTrueKHR: return "OpAssumeTrueKHR";
case OpExpectKHR: return "OpExpectKHR";
case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD";
case 5002: return "OpGroupFMinNonUniformAMD";
@ -1472,6 +1495,8 @@ const char* OpcodeString(int op)
case OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT";
case OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT";
case OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR";
case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR";
case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR";
case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR";
@ -1559,6 +1584,14 @@ const char* OpcodeString(int op)
case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM";
case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM";
case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM";
case OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM";
case OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM";
case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM";
case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM";
case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT";
case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT";
case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT";
default:
return "Bad";
@ -1678,7 +1711,7 @@ void Parameterize()
InstructionDesc[OpCooperativeMatrixStoreKHR].setResultAndType(false, false);
InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false);
InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false);
InstructionDesc[OpAssumeTrueKHR].setResultAndType(false, false);
// Specific additional context-dependent operands
ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "'Number of <<Invocation,invocations>>'");
@ -1866,6 +1899,10 @@ void Parameterize()
InstructionDesc[OpExtInst].operands.push(OperandLiteralNumber, "'Instruction'");
InstructionDesc[OpExtInst].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n...");
InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandId, "'Set'");
InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandLiteralNumber, "'Instruction'");
InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n...");
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true);
@ -2457,6 +2494,11 @@ void Parameterize()
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpAssumeTrueKHR].operands.push(OperandId, "'Condition'");
InstructionDesc[OpExpectKHR].operands.push(OperandId, "'Value'");
InstructionDesc[OpExpectKHR].operands.push(OperandId, "'ExpectedValue'");
InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
@ -2885,6 +2927,11 @@ void Parameterize()
InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandId, "'Predicate'");
InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'X'");
InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'Delta'");
InstructionDesc[OpGroupNonUniformRotateKHR].operands.push(OperandId, "'ClusterSize'", true);
InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'");
InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'");
@ -2931,6 +2978,8 @@ void Parameterize()
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
InstructionDesc[OpGroupNonUniformQuadAllKHR].operands.push(OperandId, "'Predicate'");
InstructionDesc[OpGroupNonUniformQuadAnyKHR].operands.push(OperandId, "'Predicate'");
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'");
@ -3403,6 +3452,42 @@ void Parameterize()
InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchSSDQCOM].setResultAndType(true, true);
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target texture'");
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target coordinates'");
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference texture'");
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference coordinates'");
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchWindowSSDQCOM].setResultAndType(true, true);
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target texture'");
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target coordinates'");
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference texture'");
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference coordinates'");
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchWindowSADQCOM].setResultAndType(true, true);
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target texture'");
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target coordinates'");
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference texture'");
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference coordinates'");
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchGatherSSDQCOM].setResultAndType(true, true);
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target texture'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target coordinates'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference texture'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference coordinates'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchGatherSADQCOM].setResultAndType(true, true);
InstructionDesc[OpConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpSpecConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpCompositeConstructReplicateEXT].operands.push(OperandId, "'Value'");
});
}

View File

@ -240,8 +240,8 @@ public:
OperandParameters operands;
protected:
int typePresent : 1;
int resultPresent : 1;
bool typePresent : 1;
bool resultPresent : 1;
};
// The set of objects that hold all the instruction/operand

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2020 The Khronos Group Inc.
// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@ -174,6 +174,8 @@ enum ExecutionMode {
ExecutionModeStencilRefUnchangedBackAMD = 5082,
ExecutionModeStencilRefGreaterBackAMD = 5083,
ExecutionModeStencilRefLessBackAMD = 5084,
ExecutionModeQuadDerivativesKHR = 5088,
ExecutionModeRequireFullQuadsKHR = 5089,
ExecutionModeOutputLinesEXT = 5269,
ExecutionModeOutputLinesNV = 5269,
ExecutionModeOutputPrimitivesEXT = 5270,
@ -198,6 +200,7 @@ enum ExecutionMode {
ExecutionModeNoGlobalOffsetINTEL = 5895,
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
ExecutionModeMaximallyReconvergesKHR = 6023,
ExecutionModeStreamingInterfaceINTEL = 6154,
ExecutionModeNamedBarrierCountINTEL = 6417,
ExecutionModeMax = 0x7fffffff,
@ -382,7 +385,7 @@ enum ImageOperandsShift {
ImageOperandsMax = 0x7fffffff,
};
enum ImageOperandsMask {
enum ImageOperandsMask : unsigned {
ImageOperandsMaskNone = 0,
ImageOperandsBiasMask = 0x00000001,
ImageOperandsLodMask = 0x00000002,
@ -417,7 +420,7 @@ enum FPFastMathModeShift {
FPFastMathModeMax = 0x7fffffff,
};
enum FPFastMathModeMask {
enum FPFastMathModeMask : unsigned {
FPFastMathModeMaskNone = 0,
FPFastMathModeNotNaNMask = 0x00000001,
FPFastMathModeNotInfMask = 0x00000002,
@ -515,6 +518,7 @@ enum Decoration {
DecorationNoUnsignedWrap = 4470,
DecorationWeightTextureQCOM = 4487,
DecorationBlockMatchTextureQCOM = 4488,
DecorationBlockMatchSamplerQCOM = 4499,
DecorationExplicitInterpAMD = 4999,
DecorationOverrideCoverageNV = 5248,
DecorationPassthroughNV = 5250,
@ -722,8 +726,6 @@ enum BuiltIn {
BuiltInHitTriangleVertexPositionsKHR = 5335,
BuiltInHitMicroTriangleVertexPositionsNV = 5337,
BuiltInHitMicroTriangleVertexBarycentricsNV = 5344,
BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
BuiltInHitKindBackFacingMicroTriangleNV = 5406,
BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352,
@ -731,6 +733,8 @@ enum BuiltIn {
BuiltInSMCountNV = 5375,
BuiltInWarpIDNV = 5376,
BuiltInSMIDNV = 5377,
BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
BuiltInHitKindBackFacingMicroTriangleNV = 5406,
BuiltInCullMaskKHR = 6021,
BuiltInMax = 0x7fffffff,
};
@ -741,7 +745,7 @@ enum SelectionControlShift {
SelectionControlMax = 0x7fffffff,
};
enum SelectionControlMask {
enum SelectionControlMask : unsigned {
SelectionControlMaskNone = 0,
SelectionControlFlattenMask = 0x00000001,
SelectionControlDontFlattenMask = 0x00000002,
@ -770,7 +774,7 @@ enum LoopControlShift {
LoopControlMax = 0x7fffffff,
};
enum LoopControlMask {
enum LoopControlMask : unsigned {
LoopControlMaskNone = 0,
LoopControlUnrollMask = 0x00000001,
LoopControlDontUnrollMask = 0x00000002,
@ -802,7 +806,7 @@ enum FunctionControlShift {
FunctionControlMax = 0x7fffffff,
};
enum FunctionControlMask {
enum FunctionControlMask : unsigned {
FunctionControlMaskNone = 0,
FunctionControlInlineMask = 0x00000001,
FunctionControlDontInlineMask = 0x00000002,
@ -832,7 +836,7 @@ enum MemorySemanticsShift {
MemorySemanticsMax = 0x7fffffff,
};
enum MemorySemanticsMask {
enum MemorySemanticsMask : unsigned {
MemorySemanticsMaskNone = 0,
MemorySemanticsAcquireMask = 0x00000002,
MemorySemanticsReleaseMask = 0x00000004,
@ -868,7 +872,7 @@ enum MemoryAccessShift {
MemoryAccessMax = 0x7fffffff,
};
enum MemoryAccessMask {
enum MemoryAccessMask : unsigned {
MemoryAccessMaskNone = 0,
MemoryAccessVolatileMask = 0x00000001,
MemoryAccessAlignedMask = 0x00000002,
@ -918,7 +922,7 @@ enum KernelProfilingInfoShift {
KernelProfilingInfoMax = 0x7fffffff,
};
enum KernelProfilingInfoMask {
enum KernelProfilingInfoMask : unsigned {
KernelProfilingInfoMaskNone = 0,
KernelProfilingInfoCmdExecTimeMask = 0x00000001,
};
@ -998,6 +1002,7 @@ enum Capability {
CapabilityTileImageColorReadAccessEXT = 4166,
CapabilityTileImageDepthReadAccessEXT = 4167,
CapabilityTileImageStencilReadAccessEXT = 4168,
CapabilityCooperativeMatrixLayoutsARM = 4201,
CapabilityFragmentShadingRateKHR = 4422,
CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427,
@ -1032,6 +1037,7 @@ enum Capability {
CapabilityTextureSampleWeightedQCOM = 4484,
CapabilityTextureBoxFilterQCOM = 4485,
CapabilityTextureBlockMatchQCOM = 4486,
CapabilityTextureBlockMatch2QCOM = 4498,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
@ -1039,6 +1045,7 @@ enum Capability {
CapabilityImageReadWriteLodAMD = 5015,
CapabilityInt64ImageEXT = 5016,
CapabilityShaderClockKHR = 5055,
CapabilityQuadControlKHR = 5087,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
CapabilityShaderViewportIndexLayerEXT = 5254,
@ -1099,11 +1106,12 @@ enum Capability {
CapabilityDemoteToHelperInvocation = 5379,
CapabilityDemoteToHelperInvocationEXT = 5379,
CapabilityDisplacementMicromapNV = 5380,
CapabilityRayTracingDisplacementMicromapNV = 5409,
CapabilityRayTracingOpacityMicromapEXT = 5381,
CapabilityShaderInvocationReorderNV = 5383,
CapabilityBindlessTextureNV = 5390,
CapabilityRayQueryPositionFetchKHR = 5391,
CapabilityAtomicFloat16VectorNV = 5404,
CapabilityRayTracingDisplacementMicromapNV = 5409,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
@ -1156,6 +1164,7 @@ enum Capability {
CapabilityDotProductKHR = 6019,
CapabilityRayCullMaskKHR = 6020,
CapabilityCooperativeMatrixKHR = 6022,
CapabilityReplicatedCompositesEXT = 6024,
CapabilityBitInstructions = 6025,
CapabilityGroupNonUniformRotateKHR = 6026,
CapabilityAtomicFloat32AddEXT = 6033,
@ -1185,7 +1194,7 @@ enum RayFlagsShift {
RayFlagsMax = 0x7fffffff,
};
enum RayFlagsMask {
enum RayFlagsMask : unsigned {
RayFlagsMaskNone = 0,
RayFlagsOpaqueKHRMask = 0x00000001,
RayFlagsNoOpaqueKHRMask = 0x00000002,
@ -1227,7 +1236,7 @@ enum FragmentShadingRateShift {
FragmentShadingRateMax = 0x7fffffff,
};
enum FragmentShadingRateMask {
enum FragmentShadingRateMask : unsigned {
FragmentShadingRateMaskNone = 0,
FragmentShadingRateVertical2PixelsMask = 0x00000001,
FragmentShadingRateVertical4PixelsMask = 0x00000002,
@ -1282,7 +1291,7 @@ enum CooperativeMatrixOperandsShift {
CooperativeMatrixOperandsMax = 0x7fffffff,
};
enum CooperativeMatrixOperandsMask {
enum CooperativeMatrixOperandsMask : unsigned {
CooperativeMatrixOperandsMaskNone = 0,
CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001,
CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002,
@ -1294,6 +1303,8 @@ enum CooperativeMatrixOperandsMask {
enum CooperativeMatrixLayout {
CooperativeMatrixLayoutRowMajorKHR = 0,
CooperativeMatrixLayoutColumnMajorKHR = 1,
CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202,
CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203,
CooperativeMatrixLayoutMax = 0x7fffffff,
};
@ -1660,6 +1671,7 @@ enum Op {
OpSubgroupAllEqualKHR = 4430,
OpGroupNonUniformRotateKHR = 4431,
OpSubgroupReadInvocationKHR = 4432,
OpExtInstWithForwardRefsKHR = 4433,
OpTraceRayKHR = 4445,
OpExecuteCallableKHR = 4446,
OpConvertUToAccelerationStructureKHR = 4447,
@ -1682,6 +1694,9 @@ enum Op {
OpCooperativeMatrixStoreKHR = 4458,
OpCooperativeMatrixMulAddKHR = 4459,
OpCooperativeMatrixLengthKHR = 4460,
OpConstantCompositeReplicateEXT = 4461,
OpSpecConstantCompositeReplicateEXT = 4462,
OpCompositeConstructReplicateEXT = 4463,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@ -1693,6 +1708,10 @@ enum Op {
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
OpImageBlockMatchWindowSSDQCOM = 4500,
OpImageBlockMatchWindowSADQCOM = 4501,
OpImageBlockMatchGatherSSDQCOM = 4502,
OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@ -1704,6 +1723,8 @@ enum Op {
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
OpGroupNonUniformQuadAllKHR = 5110,
OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@ -2378,6 +2399,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
case OpPtrDiff: *hasResult = true; *hasResultType = true; break;
case OpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break;
case OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break;
case OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break;
case OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break;
@ -2405,6 +2427,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break;
case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break;
case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break;
case OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
@ -2416,6 +2441,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@ -2427,6 +2456,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
case OpReadClockKHR: *hasResult = true; *hasResultType = true; break;
case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break;

View File

@ -56,6 +56,7 @@
#include <memory>
#include <vector>
#include <set>
#include <optional>
namespace spv {
@ -96,12 +97,24 @@ public:
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
virtual ~Instruction() {}
void reserveOperands(size_t count) {
operands.reserve(count);
idOperand.reserve(count);
}
void addIdOperand(Id id) {
// ids can't be 0
assert(id);
operands.push_back(id);
idOperand.push_back(true);
}
// This method is potentially dangerous as it can break assumptions
// about SSA and lack of forward references.
void setIdOperand(unsigned idx, Id id) {
assert(id);
assert(idOperand[idx]);
operands[idx] = id;
}
void addImmediateOperand(unsigned int immediate) {
operands.push_back(immediate);
idOperand.push_back(false);
@ -190,6 +203,12 @@ protected:
// SPIR-V IR block.
//
struct DebugSourceLocation {
int line;
int column;
spv::Id fileId;
};
class Block {
public:
Block(Id id, Function& parent);
@ -200,12 +219,34 @@ public:
Id getId() { return instructions.front()->getResultId(); }
Function& getParent() const { return parent; }
// Returns true if the source location is actually updated.
// Note we still need the builder to insert the line marker instruction. This is just a tracker.
bool updateDebugSourceLocation(int line, int column, spv::Id fileId) {
if (currentSourceLoc && currentSourceLoc->line == line && currentSourceLoc->column == column &&
currentSourceLoc->fileId == fileId) {
return false;
}
currentSourceLoc = DebugSourceLocation{line, column, fileId};
return true;
}
// Returns true if the scope is actually updated.
// Note we still need the builder to insert the debug scope instruction. This is just a tracker.
bool updateDebugScope(spv::Id scopeId) {
assert(scopeId);
if (currentDebugScope && *currentDebugScope == scopeId) {
return false;
}
currentDebugScope = scopeId;
return true;
}
void addInstruction(std::unique_ptr<Instruction> inst);
void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
const std::vector<Block*>& getPredecessors() const { return predecessors; }
const std::vector<Block*>& getSuccessors() const { return successors; }
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
std::vector<std::unique_ptr<Instruction> >& getInstructions() {
return instructions;
}
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
@ -292,6 +333,12 @@ protected:
std::vector<std::unique_ptr<Instruction> > localVariables;
Function& parent;
// Track source location of the last source location marker instruction.
std::optional<DebugSourceLocation> currentSourceLoc;
// Track scope of the last debug scope instruction.
std::optional<spv::Id> currentDebugScope;
// track whether this block is known to be uncreachable (not necessarily
// true for all unreachable blocks, but should be set at least
// for the extraneous ones introduced by the builder).
@ -363,6 +410,7 @@ public:
void setDebugLineInfo(Id fileName, int line, int column) {
lineInstruction = std::unique_ptr<Instruction>{new Instruction(OpLine)};
lineInstruction->reserveOperands(3);
lineInstruction->addIdOperand(fileName);
lineInstruction->addImmediateOperand(line);
lineInstruction->addImmediateOperand(column);
@ -486,6 +534,7 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
linkType(linkage)
{
// OpFunction
functionInstruction.reserveOperands(2);
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
functionInstruction.addIdOperand(functionType);
parent.mapInstruction(&functionInstruction);

View File

@ -44,11 +44,10 @@
#include "glslang/Public/ResourceLimits.h"
#include "Worklist.h"
#include "DirStackFileIncluder.h"
#include "./../glslang/Include/ShHandle.h"
#include "./../glslang/Public/ShaderLang.h"
#include "../glslang/MachineIndependent/localintermediate.h"
#include "../SPIRV/GlslangToSpv.h"
#include "../SPIRV/GLSL.std.450.h"
#include "../SPIRV/doc.h"
#include "../SPIRV/disassemble.h"
#include <array>
@ -109,6 +108,7 @@ enum TOptions : uint64_t {
EOptionInvertY = (1ull << 30),
EOptionDumpBareVersion = (1ull << 31),
EOptionCompileOnly = (1ull << 32),
EOptionDisplayErrorColumn = (1ull << 33),
};
bool targetHlslFunctionality1 = false;
bool SpvToolsDisassembler = false;
@ -181,6 +181,7 @@ bool HlslEnable16BitTypes = false;
bool HlslDX9compatible = false;
bool HlslDxPositionW = false;
bool EnhancedMsgs = false;
bool AbsolutePath = false;
bool DumpBuiltinSymbols = false;
std::vector<std::string> IncludeDirectoryList;
@ -726,6 +727,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
HlslDxPositionW = true;
} else if (lowerword == "enhanced-msgs") {
EnhancedMsgs = true;
} else if (lowerword == "absolute-path") {
AbsolutePath = true;
} else if (lowerword == "auto-sampled-textures") {
autoSampledTextures = true;
} else if (lowerword == "invert-y" || // synonyms
@ -894,6 +897,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options |= EOptionDumpVersions;
} else if (lowerword == "no-link") {
Options |= EOptionCompileOnly;
} else if (lowerword == "error-column") {
Options |= EOptionDisplayErrorColumn;
} else if (lowerword == "help") {
usage();
break;
@ -1158,6 +1163,10 @@ void SetMessageOptions(EShMessages& messages)
messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable);
if (EnhancedMsgs)
messages = (EShMessages)(messages | EShMsgEnhanced);
if (AbsolutePath)
messages = (EShMessages)(messages | EShMsgAbsolutePath);
if (Options & EOptionDisplayErrorColumn)
messages = (EShMessages)(messages | EShMsgDisplayErrorColumn);
}
//
@ -1189,6 +1198,7 @@ void CompileShaders(glslang::TWorklist& worklist)
if (compiler == nullptr)
return;
CompileFile(workItem->name.c_str(), compiler);
if (! (Options & EOptionSuppressInfolog))
@ -1497,6 +1507,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
std::vector<std::string> outputFiles;
#ifdef ENABLE_SPIRV
// Dump SPIR-V
if (Options & EOptionSpv) {
CompileOrLinkFailed.fetch_or(CompileFailed);
@ -1559,6 +1570,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
}
}
}
#endif
CompileOrLinkFailed.fetch_or(CompileFailed);
CompileOrLinkFailed.fetch_or(LinkFailed);
@ -1657,21 +1669,31 @@ int singleMain()
}
if (Options & EOptionDumpBareVersion) {
printf("%d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR,
int spirvGeneratorVersion = 0;
#ifdef ENABLE_SPIRV
spirvGeneratorVersion = glslang::GetSpirvGeneratorVersion();
#endif
printf("%d:%d.%d.%d%s\n", spirvGeneratorVersion, GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR,
GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
if (workList.empty())
return ESuccess;
} else if (Options & EOptionDumpVersions) {
printf("Glslang Version: %d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR,
int spirvGeneratorVersion = 0;
#ifdef ENABLE_SPIRV
spirvGeneratorVersion = glslang::GetSpirvGeneratorVersion();
#endif
printf("Glslang Version: %d:%d.%d.%d%s\n", spirvGeneratorVersion, GLSLANG_VERSION_MAJOR,
GLSLANG_VERSION_MINOR, GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
printf("ESSL Version: %s\n", glslang::GetEsslVersionString());
printf("GLSL Version: %s\n", glslang::GetGlslVersionString());
std::string spirvVersion;
#if ENABLE_SPIRV
glslang::GetSpirvVersion(spirvVersion);
#endif
printf("SPIR-V Version %s\n", spirvVersion.c_str());
printf("GLSL.std.450 Version %d, Revision %d\n", GLSLstd450Version, GLSLstd450Revision);
printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
printf("SPIR-V Generator Version %d\n", glslang::GetSpirvGeneratorVersion());
printf("SPIR-V Generator Version %d\n", spirvGeneratorVersion);
printf("GL_KHR_vulkan_glsl version %d\n", 100);
printf("ARB_GL_gl_spirv version %d\n", 100);
if (workList.empty())
@ -1877,7 +1899,7 @@ void CompileFile(const char* fileName, ShHandle compiler)
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
// ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, GetResources(), 0,
(Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
(Options & EOptionDefaultDesktop) ? 110 : 100, false, messages, fileName);
// const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
// "or should be l", "ine 1", "string 5\n", "float glo", "bal",
// ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
@ -1992,6 +2014,7 @@ void usage()
" without explicit bindings\n"
" --auto-map-locations | --aml automatically locate input/output lacking\n"
" 'location' (fragile, not cross stage)\n"
" --absolute-path Prints absolute path for messages\n"
" --auto-sampled-textures Removes sampler variables and converts\n"
" existing textures to sampled textures\n"
" --client {vulkan<ver>|opengl<ver>} see -V and -G\n"
@ -2016,6 +2039,7 @@ void usage()
" shaders compatible with DirectX\n"
" --invert-y | --iy invert position.Y output in vertex shader\n"
" --enhanced-msgs print more readable error messages (GLSL only)\n"
" --error-column display the column of the error along the line\n"
" --keep-uncalled | --ku don't eliminate uncalled functions\n"
" --nan-clamp favor non-NaN operand in min, max, and clamp\n"
" --no-storage-format | --nsf use Unknown image format\n"
@ -2159,6 +2183,20 @@ char* ReadFileData(const char* fileName)
fseek(in, 0, SEEK_SET);
if (count > 3) {
unsigned char head[3];
if (fread(head, 1, 3, in) == 3) {
if (head[0] == 0xef && head[1] == 0xbb && head[2] == 0xbf) {
// skip BOM
count -= 3;
} else {
fseek(in, 0, SEEK_SET);
}
} else {
Error("can't read input file");
}
}
char* return_data = (char*)malloc(count + 1); // freed in FreeFileData()
if ((int)fread(return_data, 1, count, in) != count) {
free(return_data);

View File

@ -35,7 +35,6 @@
#ifndef WORKLIST_H_INCLUDED
#define WORKLIST_H_INCLUDED
#include "../glslang/OSDependent/osinclude.h"
#include <list>
#include <mutex>
#include <string>

View File

@ -34,9 +34,9 @@
#ifndef GLSLANG_BUILD_INFO
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 13
#define GLSLANG_VERSION_MINOR 1
#define GLSLANG_VERSION_PATCH 1
#define GLSLANG_VERSION_MAJOR 14
#define GLSLANG_VERSION_MINOR 3
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""
#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \

View File

@ -34,9 +34,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "StandAlone/DirStackFileIncluder.h"
#include "glslang/Public/ResourceLimits.h"
#include "glslang/Public/ShaderLang.h"
#include "glslang/Include/ShHandle.h"
#include "glslang/Include/BaseTypes.h"
#include "glslang/Include/ResourceLimits.h"
#include "glslang/Include/Types.h"
#include "glslang/MachineIndependent/iomapper.h"
#include "glslang/MachineIndependent/Versions.h"
#include "glslang/MachineIndependent/localintermediate.h"
@ -54,6 +58,7 @@ static_assert(int(GLSLANG_REFLECTION_COUNT) == EShReflectionCount, "");
static_assert(int(GLSLANG_PROFILE_COUNT) == EProfileCount, "");
static_assert(sizeof(glslang_limits_t) == sizeof(TLimits), "");
static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), "");
static_assert(sizeof(glslang_version_t) == sizeof(glslang::Version), "");
typedef struct glslang_shader_s {
glslang::TShader* shader;
@ -141,6 +146,11 @@ private:
void* context;
};
GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version)
{
*reinterpret_cast<glslang::Version*>(version) = glslang::GetVersion();
}
GLSLANG_EXPORT int glslang_initialize_process() { return static_cast<int>(glslang::InitializeProcess()); }
GLSLANG_EXPORT void glslang_finalize_process() { glslang::FinalizeProcess(); }
@ -205,6 +215,9 @@ static int c_shader_messages(glslang_messages_t messages)
CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization);
CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible);
CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable);
CONVERT_MSG(GLSLANG_MSG_ENHANCED, EShMsgEnhanced);
CONVERT_MSG(GLSLANG_MSG_ABSOLUTE_PATH, EShMsgAbsolutePath);
CONVERT_MSG(GLSLANG_MSG_DISPLAY_ERROR_COLUMN, EShMsgDisplayErrorColumn);
return res;
#undef CONVERT_MSG
}
@ -367,11 +380,25 @@ GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, in
shader->shader->setOverrideVersion(version);
}
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding) {
shader->shader->setGlobalUniformSet(set);
shader->shader->setGlobalUniformBinding(binding);
}
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name) {
shader->shader->setGlobalUniformBlockName(name);
}
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
{
return shader->preprocessedGLSL.c_str();
}
GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code)
{
shader->preprocessedGLSL.assign(code);
}
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input)
{
DirStackFileIncluder dirStackFileIncluder;
@ -458,6 +485,11 @@ GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program)
return (int)program->program->mapIO();
}
GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper)
{
return (int)program->program->mapIO(reinterpret_cast<glslang::TDefaultGlslIoResolver*>(resolver), reinterpret_cast<glslang::TGlslIoMapper*>(mapper));
}
GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program)
{
return program->program->getInfoLog();
@ -467,3 +499,30 @@ GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t*
{
return program->program->getInfoDebugLog();
}
GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create()
{
return reinterpret_cast<glslang_mapper_t*>(new glslang::TGlslIoMapper());
}
GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper)
{
if (!mapper)
return;
delete reinterpret_cast<glslang::TGlslIoMapper* >(mapper);
}
GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage)
{
glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
return reinterpret_cast<glslang_resolver_t*>(new glslang::TDefaultGlslIoResolver(reinterpret_cast<const glslang::TIntermediate&>(*intermediate)));
}
GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver)
{
if (!resolver)
return;
delete reinterpret_cast<glslang::TDefaultGlslIoResolver* >(resolver);
}

View File

@ -391,6 +391,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
case EvqOut:
case EvqInOut:
parseContext.error(token.loc, "in/out qualifiers are only valid on parameters", token.string->c_str(), "");
break;
default:
break;
}

View File

@ -43,8 +43,6 @@
#include "../MachineIndependent/Scan.h"
#include "../MachineIndependent/preprocessor/PpContext.h"
#include "../OSDependent/osinclude.h"
#include <algorithm>
#include <functional>
#include <cctype>
@ -402,7 +400,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
case EOpLeftShiftAssign:
case EOpRightShiftAssign:
isModifyOp = true;
// fall through...
[[fallthrough]];
case EOpAssign:
{
// Since this is an lvalue, we'll convert an image load to a sequence like this
@ -962,14 +960,11 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
return addConstructor(loc, base, type);
}
}
if (base->getVectorSize() == 1) {
// Use EOpIndexDirect (below) with vec1.x so that it remains l-value (Test/hlsl.swizzle.vec1.comp)
if (base->getVectorSize() == 1 && selectors.size() > 1) {
TType scalarType(base->getBasicType(), EvqTemporary, 1);
if (selectors.size() == 1)
return addConstructor(loc, base, scalarType);
else {
TType vectorType(base->getBasicType(), EvqTemporary, selectors.size());
return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType);
}
TType vectorType(base->getBasicType(), EvqTemporary, selectors.size());
return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType);
}
if (base->getType().getQualifier().isFrontEndConstant())
@ -4507,13 +4502,13 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
int cmpValues = 0; // 1 if there is a compare value (handier than a bool below)
switch (op) {
case EOpMethodGatherCmpRed: cmpValues = 1; // fall through
case EOpMethodGatherCmpRed: cmpValues = 1; [[fallthrough]];
case EOpMethodGatherRed: channel = 0; break;
case EOpMethodGatherCmpGreen: cmpValues = 1; // fall through
case EOpMethodGatherCmpGreen: cmpValues = 1; [[fallthrough]];
case EOpMethodGatherGreen: channel = 1; break;
case EOpMethodGatherCmpBlue: cmpValues = 1; // fall through
case EOpMethodGatherCmpBlue: cmpValues = 1; [[fallthrough]];
case EOpMethodGatherBlue: channel = 2; break;
case EOpMethodGatherCmpAlpha: cmpValues = 1; // fall through
case EOpMethodGatherCmpAlpha: cmpValues = 1; [[fallthrough]];
case EOpMethodGatherAlpha: channel = 3; break;
default: assert(0); break;
}
@ -6062,7 +6057,7 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
unaryArg = callNode.getAsUnaryNode()->getOperand();
arg0 = unaryArg;
}
const TIntermSequence& aggArgs = *argp; // only valid when unaryArg is nullptr
const TIntermSequence& aggArgs = argp ? *argp : TIntermSequence(); // only valid when unaryArg is nullptr
switch (callNode.getOp()) {
case EOpTextureGather:
@ -9551,6 +9546,8 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const
return language == EShLangTessEvaluation;
case EbvTessCoord:
return language == EShLangTessEvaluation;
case EbvViewIndex:
return language != EShLangCompute;
default:
return false;
}
@ -9656,6 +9653,10 @@ void HlslParseContext::correctOutput(TQualifier& qualifier)
if (language != EShLangTessControl)
qualifier.patch = false;
// Fixes Test/hlsl.entry-inout.vert (SV_Position will not become a varying).
if (qualifier.builtIn == EbvNone)
qualifier.builtIn = qualifier.declaredBuiltIn;
switch (qualifier.builtIn) {
case EbvFragDepth:
intermediate.setDepthReplacing();

View File

@ -512,6 +512,7 @@ void HlslScanContext::fillInKeywordMap()
(*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
(*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
(*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
(*SemanticMap)["SV_VIEWID"] = EbvViewIndex;
(*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
(*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
(*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;

View File

@ -42,8 +42,6 @@
#include "../MachineIndependent/Scan.h"
#include "../MachineIndependent/preprocessor/PpContext.h"
#include "../OSDependent/osinclude.h"
#include <algorithm>
#include <array>
#include <cctype>

2
3rdparty/glslang/glslang/Include/BaseTypes.h vendored Executable file → Normal file
View File

@ -268,7 +268,6 @@ enum TBuiltInVariable {
EbvRayTmin,
EbvRayTmax,
EbvCullMask,
EbvHitT,
EbvHitKind,
EbvObjectToWorld,
EbvObjectToWorld3x4,
@ -495,7 +494,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
case EbvRayTmin: return "ObjectRayTminNV";
case EbvRayTmax: return "ObjectRayTmaxNV";
case EbvHitT: return "HitTNV";
case EbvHitKind: return "HitKindNV";
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
case EbvObjectToWorld: return "ObjectToWorldNV";

View File

@ -96,6 +96,11 @@ std::string to_string(const T& val) {
#pragma warning(disable : 4201) // nameless union
#endif
// Allow compilation to WASI which does not support threads yet.
#ifdef __wasi__
#define DISABLE_THREAD_SUPPORT
#endif
#include "PoolAlloc.h"
//
@ -161,6 +166,11 @@ template<class T> inline T* NewPoolObject(T, int instances)
return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances];
}
inline bool StartsWith(TString const &str, const char *prefix)
{
return str.compare(0, strlen(prefix), prefix) == 0;
}
//
// Pool allocator versions of vectors, lists, and maps
//
@ -294,34 +304,6 @@ template <class T> int IntLog2(T n)
return result;
}
inline bool IsInfinity(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return true;
default:
return false;
}
#else
return std::isinf(x);
#endif
}
inline bool IsNan(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return true;
default:
return false;
}
#else
return std::isnan(x);
#endif
}
} // end namespace glslang
#endif // _COMMON_INCLUDED_

View File

@ -503,7 +503,7 @@ public:
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
case EbtInt16: returnValue.setI16Const(i16Const % constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;

View File

@ -36,6 +36,7 @@
#define _INFOSINK_INCLUDED_
#include "../Include/Common.h"
#include <filesystem>
#include <cmath>
namespace glslang {
@ -67,7 +68,7 @@ enum TOutputStream {
//
class TInfoSinkBase {
public:
TInfoSinkBase() : outputStream(4) {}
TInfoSinkBase() : outputStream(4), shaderFileName(nullptr) {}
void erase() { sink.erase(); }
TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
TInfoSinkBase& operator<<(char c) { append(1, c); return *this; }
@ -94,11 +95,26 @@ public:
default: append("UNKNOWN ERROR: "); break;
}
}
void location(const TSourceLoc& loc) {
void location(const TSourceLoc& loc, bool absolute = false, bool displayColumn = false) {
const int maxSize = 24;
char locText[maxSize];
snprintf(locText, maxSize, ":%d", loc.line);
append(loc.getStringNameOrNum(false).c_str());
if (displayColumn) {
snprintf(locText, maxSize, ":%d:%d", loc.line, loc.column);
} else {
snprintf(locText, maxSize, ":%d", loc.line);
}
if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) {
append(std::filesystem::absolute(shaderFileName).string());
} else {
std::string location = loc.getStringNameOrNum(false);
if (absolute) {
append(std::filesystem::absolute(location).string());
} else {
append(location);
}
}
append(locText);
append(": ");
}
@ -107,9 +123,11 @@ public:
append(s);
append("\n");
}
void message(TPrefixType message, const char* s, const TSourceLoc& loc) {
void message(TPrefixType message, const char* s, const TSourceLoc& loc, bool absolute = false,
bool displayColumn = false)
{
prefix(message);
location(loc);
location(loc, absolute, displayColumn);
append(s);
append("\n");
}
@ -119,6 +137,11 @@ public:
outputStream = output;
}
void setShaderFileName(const char* file = nullptr)
{
shaderFileName = file;
}
protected:
void append(const char* s);
@ -131,6 +154,7 @@ protected:
void appendToStream(const char* s);
TPersistString sink;
int outputStream;
const char* shaderFileName;
};
} // end namespace glslang

View File

@ -573,7 +573,8 @@ public:
}
const char* semanticName;
TStorageQualifier storage : 6;
TStorageQualifier storage : 7;
static_assert(EvqLast < 64, "need to increase size of TStorageQualifier bitfields!");
TBuiltInVariable builtIn : 9;
TBuiltInVariable declaredBuiltIn : 9;
static_assert(EbvLast < 256, "need to increase size of TBuiltInVariable bitfields!");
@ -852,6 +853,8 @@ public:
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
layoutSecondaryViewportRelativeOffset = -2048;
layoutShaderRecord = false;
layoutFullQuads = false;
layoutQuadDeriv = false;
layoutHitObjectShaderRecordNV = false;
layoutBindlessSampler = false;
layoutBindlessImage = false;
@ -948,6 +951,8 @@ public:
bool layoutViewportRelative;
int layoutSecondaryViewportRelativeOffset;
bool layoutShaderRecord;
bool layoutFullQuads;
bool layoutQuadDeriv;
bool layoutHitObjectShaderRecordNV;
// GL_EXT_spirv_intrinsics
@ -1055,6 +1060,8 @@ public:
TLayoutFormat getFormat() const { return layoutFormat; }
bool isPushConstant() const { return layoutPushConstant; }
bool isShaderRecord() const { return layoutShaderRecord; }
bool isFullQuads() const { return layoutFullQuads; }
bool isQuadDeriv() const { return layoutQuadDeriv; }
bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; }
bool hasBufferReference() const { return layoutBufferReference; }
bool hasBufferReferenceAlign() const
@ -1075,7 +1082,7 @@ public:
}
// GL_EXT_spirv_intrinsics
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
bool hasSpirvDecorate() const { return spirvDecorate != nullptr; }
void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
@ -1428,13 +1435,25 @@ class TTypeParameters {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr) {}
TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr), spirvType(nullptr) {}
TBasicType basicType;
TArraySizes *arraySizes;
TSpirvType *spirvType;
bool operator==(const TTypeParameters& rhs) const { return basicType == rhs.basicType && *arraySizes == *rhs.arraySizes; }
bool operator!=(const TTypeParameters& rhs) const { return basicType != rhs.basicType || *arraySizes != *rhs.arraySizes; }
bool operator==(const TTypeParameters& rhs) const
{
bool same = basicType == rhs.basicType && *arraySizes == *rhs.arraySizes;
if (same && basicType == EbtSpirvType) {
assert(spirvType && rhs.spirvType);
return *spirvType == *rhs.spirvType;
}
return same;
}
bool operator!=(const TTypeParameters& rhs) const
{
return !(*this == rhs);
}
};
//
@ -1451,9 +1470,9 @@ public:
TSampler sampler;
TQualifier qualifier;
TShaderQualifiers shaderQualifiers;
int vectorSize : 4;
int matrixCols : 4;
int matrixRows : 4;
uint32_t vectorSize : 4;
uint32_t matrixCols : 4;
uint32_t matrixRows : 4;
bool coopmatNV : 1;
bool coopmatKHR : 1;
TArraySizes* arraySizes;
@ -1470,7 +1489,7 @@ public:
void initType(const TSourceLoc& l)
{
basicType = EbtVoid;
vectorSize = 1;
vectorSize = 1u;
matrixRows = 0;
matrixCols = 0;
arraySizes = nullptr;
@ -1501,19 +1520,22 @@ public:
{
matrixRows = 0;
matrixCols = 0;
vectorSize = s;
assert(s >= 0);
vectorSize = static_cast<uint32_t>(s) & 0b1111;
}
void setMatrix(int c, int r)
{
matrixRows = r;
matrixCols = c;
assert(r >= 0);
matrixRows = static_cast<uint32_t>(r) & 0b1111;
assert(c >= 0);
matrixCols = static_cast<uint32_t>(c) & 0b1111;
vectorSize = 0;
}
bool isScalar() const
{
return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
return matrixCols == 0u && vectorSize == 1u && arraySizes == nullptr && userDef == nullptr;
}
// GL_EXT_spirv_intrinsics
@ -1535,10 +1557,14 @@ public:
// for "empty" type (no args) or simple scalar/vector/matrix
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
assert(mc >= 0);
assert(mr >= 0);
sampler.clear();
qualifier.clear();
qualifier.storage = q;
@ -1547,10 +1573,14 @@ public:
// for explicit precision qualifier
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
assert(mc >= 0);
assert(mr >= 0);
sampler.clear();
qualifier.clear();
qualifier.storage = q;
@ -1561,7 +1591,7 @@ public:
// for turning a TPublicType into a TType, using a shallow copy
explicit TType(const TPublicType& p) :
basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(-1),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
spirvType(p.spirvType)
{
@ -1600,16 +1630,23 @@ public:
}
if (p.isCoopmatKHR() && p.typeParameters && p.typeParameters->arraySizes->getNumDims() > 0) {
basicType = p.typeParameters->basicType;
if (isSpirvType()) {
assert(p.typeParameters->spirvType);
spirvType = p.typeParameters->spirvType;
}
if (p.typeParameters->arraySizes->getNumDims() == 4) {
coopmatKHRuse = p.typeParameters->arraySizes->getDimSize(3);
const int dimSize = p.typeParameters->arraySizes->getDimSize(3);
assert(dimSize >= 0);
coopmatKHRuse = static_cast<uint32_t>(dimSize) & 0b111;
coopmatKHRUseValid = true;
p.typeParameters->arraySizes->removeLastSize();
}
}
}
// for construction of sampler types
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
{
@ -1655,14 +1692,15 @@ public:
} else if (isCoopMat()) {
coopmatNV = false;
coopmatKHR = false;
coopmatKHRuse = -1;
coopmatKHRuse = 0;
coopmatKHRUseValid = false;
typeParameters = nullptr;
}
}
}
// for making structures, ...
TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1672,7 +1710,7 @@ public:
}
// For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1681,7 +1719,7 @@ public:
}
// for block reference (first parameter must be EbtReference)
explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
@ -1719,6 +1757,7 @@ public:
coopmatNV = copyOf.isCoopMatNV();
coopmatKHR = copyOf.isCoopMatKHR();
coopmatKHRuse = copyOf.coopmatKHRuse;
coopmatKHRUseValid = copyOf.coopmatKHRUseValid;
}
// Make complete copy of the whole type graph rooted at 'copyOf'.
@ -1748,7 +1787,7 @@ public:
void makeVector() { vector1 = true; }
virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; }
virtual void hideMember() { basicType = EbtVoid; vectorSize = 1u; }
virtual bool hiddenMember() const { return basicType == EbtVoid; }
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
@ -1788,9 +1827,9 @@ public:
virtual TQualifier& getQualifier() { return qualifier; }
virtual const TQualifier& getQualifier() const { return qualifier; }
virtual int getVectorSize() const { return vectorSize; } // returns 1 for either scalar or vector of size 1, valid for both
virtual int getMatrixCols() const { return matrixCols; }
virtual int getMatrixRows() const { return matrixRows; }
virtual int getVectorSize() const { return static_cast<int>(vectorSize); } // returns 1 for either scalar or vector of size 1, valid for both
virtual int getMatrixCols() const { return static_cast<int>(matrixCols); }
virtual int getMatrixRows() const { return static_cast<int>(matrixRows); }
virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); }
virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); }
virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); }
@ -1805,7 +1844,7 @@ public:
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
virtual bool isVector() const { return vectorSize > 1 || vector1; }
virtual bool isVector() const { return vectorSize > 1u || vector1; }
virtual bool isMatrix() const { return matrixCols ? true : false; }
virtual bool isArray() const { return arraySizes != nullptr; }
virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
@ -1855,7 +1894,7 @@ public:
bool isCoopMatKHR() const { return coopmatKHR; }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
int getCoopMatKHRuse() const { return coopmatKHRuse; }
int getCoopMatKHRuse() const { return static_cast<int>(coopmatKHRuse); }
// return true if this type contains any subtype which satisfies the given predicate.
template <typename P>
@ -2096,7 +2135,7 @@ public:
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
if (getQualifiers) {
if (qualifier.hasSprivDecorate())
if (qualifier.hasSpirvDecorate())
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
if (qualifier.hasLayout()) {
@ -2190,6 +2229,10 @@ public:
if (qualifier.layoutShaderRecord)
appendStr(" shaderRecordNV");
if (qualifier.layoutFullQuads)
appendStr(" full_quads");
if (qualifier.layoutQuadDeriv)
appendStr(" quad_derivatives");
if (qualifier.layoutHitObjectShaderRecordNV)
appendStr(" hitobjectshaderrecordnv");
@ -2395,7 +2438,7 @@ public:
if (i != (int)typeParameters->arraySizes->getNumDims() - 1)
appendStr(", ");
}
if (coopmatKHRuse != -1) {
if (coopmatKHRUseValid) {
appendStr(", ");
appendInt(coopmatKHRuse);
}
@ -2464,11 +2507,14 @@ public:
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
void setBasicType(const TBasicType& t) { basicType = t; }
void setVectorSize(int s) { vectorSize = s; }
void setVectorSize(int s) {
assert(s >= 0);
vectorSize = static_cast<uint32_t>(s) & 0b1111;
}
int computeNumComponents() const
{
int components = 0;
uint32_t components = 0;
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
@ -2482,7 +2528,7 @@ public:
components *= arraySizes->getCumulativeSize();
}
return components;
return static_cast<int>(components);
}
// append this type's mangled name to the passed in 'name'
@ -2689,7 +2735,8 @@ public:
if (isCoopMatKHR() && right.isCoopMatKHR()) {
return ((getBasicType() == right.getBasicType()) || (getBasicType() == EbtCoopmat) ||
(right.getBasicType() == EbtCoopmat)) &&
typeParameters == nullptr && right.typeParameters != nullptr;
((typeParameters == nullptr && right.typeParameters != nullptr) ||
(typeParameters != nullptr && right.typeParameters == nullptr));
}
return false;
}
@ -2795,6 +2842,7 @@ protected:
typeParameters = new TTypeParameters;
typeParameters->arraySizes = new TArraySizes;
*typeParameters->arraySizes = *copyOf.typeParameters->arraySizes;
*typeParameters->spirvType = *copyOf.typeParameters->spirvType;
typeParameters->basicType = copyOf.basicType;
}
@ -2825,9 +2873,9 @@ protected:
void buildMangledName(TString&) const;
TBasicType basicType : 8;
int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
int matrixCols : 4;
int matrixRows : 4;
uint32_t vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
uint32_t matrixCols : 4;
uint32_t matrixRows : 4;
bool vector1 : 1; // Backward-compatible tracking of a 1-component vector distinguished from a scalar.
// GLSL 4.5 never has a 1-component vector; so this will always be false until such
// functionality is added.
@ -2835,7 +2883,8 @@ protected:
// from a scalar.
bool coopmatNV : 1;
bool coopmatKHR : 1;
int coopmatKHRuse : 4; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
uint32_t coopmatKHRuse : 3; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
bool coopmatKHRUseValid : 1; // True if coopmatKHRuse has been set
TQualifier qualifier;
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types

View File

@ -37,9 +37,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include "glslang_c_shader_types.h"
#include "visibility.h"
typedef struct glslang_shader_s glslang_shader_t;
typedef struct glslang_program_s glslang_program_t;
typedef struct glslang_mapper_s glslang_mapper_t;
typedef struct glslang_resolver_s glslang_resolver_t;
/* Version counterpart */
typedef struct glslang_version_s {
int major;
int minor;
int patch;
const char* flavor;
} glslang_version_t;
/* TLimits counterpart */
typedef struct glslang_limits_s {
@ -227,27 +238,14 @@ typedef struct glslang_spv_options_s {
bool emit_nonsemantic_shader_debug_info;
bool emit_nonsemantic_shader_debug_source;
bool compile_only;
bool optimize_allow_expanded_id_bound;
} glslang_spv_options_t;
#ifdef __cplusplus
extern "C" {
#endif
#ifdef GLSLANG_IS_SHARED_LIBRARY
#ifdef _WIN32
#ifdef GLSLANG_EXPORTING
#define GLSLANG_EXPORT __declspec(dllexport)
#else
#define GLSLANG_EXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define GLSLANG_EXPORT __attribute__((visibility("default")))
#endif
#endif // GLSLANG_IS_SHARED_LIBRARY
#ifndef GLSLANG_EXPORT
#define GLSLANG_EXPORT
#endif
GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version);
GLSLANG_EXPORT int glslang_initialize_process(void);
GLSLANG_EXPORT void glslang_finalize_process(void);
@ -259,9 +257,12 @@ GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glsla
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set);
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t
GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version);
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding);
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name);
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);
GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code);
GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader);
GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader);
@ -272,6 +273,7 @@ GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages
GLSLANG_EXPORT void glslang_program_add_source_text(glslang_program_t* program, glslang_stage_t stage, const char* text, size_t len);
GLSLANG_EXPORT void glslang_program_set_source_file(glslang_program_t* program, glslang_stage_t stage, const char* file);
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program);
GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper);
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage);
GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_t* program, glslang_stage_t stage, glslang_spv_options_t* spv_options);
GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program);
@ -281,6 +283,12 @@ GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t*
GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program);
GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program);
GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create();
GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper);
GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage);
GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver);
#ifdef __cplusplus
}
#endif

View File

@ -157,23 +157,25 @@ typedef enum {
/* EShMessages counterpart */
typedef enum {
GLSLANG_MSG_DEFAULT_BIT = 0,
GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0),
GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1),
GLSLANG_MSG_AST_BIT = (1 << 2),
GLSLANG_MSG_SPV_RULES_BIT = (1 << 3),
GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4),
GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5),
GLSLANG_MSG_READ_HLSL_BIT = (1 << 6),
GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7),
GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8),
GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9),
GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10),
GLSLANG_MSG_DEFAULT_BIT = 0,
GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0),
GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1),
GLSLANG_MSG_AST_BIT = (1 << 2),
GLSLANG_MSG_SPV_RULES_BIT = (1 << 3),
GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4),
GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5),
GLSLANG_MSG_READ_HLSL_BIT = (1 << 6),
GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7),
GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8),
GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9),
GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10),
GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11),
GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12),
GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13),
GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14),
GLSLANG_MSG_ENHANCED = (1 << 15),
GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12),
GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13),
GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14),
GLSLANG_MSG_ENHANCED = (1 << 15),
GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16),
GLSLANG_MSG_DISPLAY_ERROR_COLUMN = (1 << 17),
LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT),
} glslang_messages_t;

View File

@ -1,7 +1,7 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2016 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
@ -48,14 +48,9 @@
#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H
#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning(disable : 4464) // relative include path contains '..'
#pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
#endif
#include "../Include/Common.h"
#include "../Include/Types.h"
#include "../Include/ConstantUnion.h"
#include "Common.h"
#include "Types.h"
#include "ConstantUnion.h"
namespace glslang {
@ -511,6 +506,8 @@ enum TOperator {
EOpSubgroupShuffleXor,
EOpSubgroupShuffleUp,
EOpSubgroupShuffleDown,
EOpSubgroupRotate,
EOpSubgroupClusteredRotate,
EOpSubgroupAdd,
EOpSubgroupMul,
EOpSubgroupMin,
@ -543,6 +540,8 @@ enum TOperator {
EOpSubgroupQuadSwapHorizontal,
EOpSubgroupQuadSwapVertical,
EOpSubgroupQuadSwapDiagonal,
EOpSubgroupQuadAll,
EOpSubgroupQuadAny,
EOpSubgroupPartition,
EOpSubgroupPartitionedAdd,
@ -1092,6 +1091,10 @@ enum TOperator {
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
// GL_EXT_expect_assume
EOpAssumeEXT,
EOpExpectEXT,
// Shader Clock Ops
EOpReadClockSubgroupKHR,
EOpReadClockDeviceKHR,
@ -1108,6 +1111,12 @@ enum TOperator {
EOpImageBoxFilterQCOM,
EOpImageBlockMatchSADQCOM,
EOpImageBlockMatchSSDQCOM,
// Image processing2
EOpImageBlockMatchWindowSSDQCOM,
EOpImageBlockMatchWindowSADQCOM,
EOpImageBlockMatchGatherSSDQCOM,
EOpImageBlockMatchGatherSADQCOM,
};
enum TLinkType {

View File

@ -1,5 +1,6 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2023 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -31,19 +32,20 @@
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef __INITIALIZEDLL_H
#define __INITIALIZEDLL_H
#ifdef GLSLANG_IS_SHARED_LIBRARY
#ifdef _WIN32
#ifdef GLSLANG_EXPORTING
#define GLSLANG_EXPORT __declspec(dllexport)
#else
#define GLSLANG_EXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define GLSLANG_EXPORT __attribute__((visibility("default")))
#endif
#endif // GLSLANG_IS_SHARED_LIBRARY
#include "../glslang/OSDependent/osinclude.h"
#ifndef GLSLANG_EXPORT
#define GLSLANG_EXPORT
#endif
namespace glslang {
inline bool InitProcess() { return true; } // DEPRECATED
inline bool InitThread() { return true; } // DEPRECATED
inline bool DetachThread() { return true; } // DEPRECATED
inline bool DetachProcess() { return true; } // DEPRECATED
} // end namespace glslang
#endif // __INITIALIZEDLL_H

View File

@ -507,7 +507,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
case EbtInt64: {
int64_t i64val = unionArray[i].getI64Const();
newConstArray[i].setI64Const(i64val == INT64_MIN ? INT64_MIN : -i64val);
break;
}
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
default:
return nullptr;
@ -628,12 +632,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpIsNan:
{
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
newConstArray[i].setBConst(std::isnan(unionArray[i].getDConst()));
break;
}
case EOpIsInf:
{
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
newConstArray[i].setBConst(std::isinf(unionArray[i].getDConst()));
break;
}
@ -689,7 +693,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpConvInt64ToBool:
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
case EOpConvUint64ToBool:
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
newConstArray[i].setBConst(unionArray[i].getU64Const() != 0); break;
case EOpConvFloat16ToBool:
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
@ -1009,6 +1013,12 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(),
children[2]->getAsTyped()->getType().getVectorSize());
break;
case EOpMul:
{
TIntermConstantUnion* left = children[0]->getAsConstantUnion();
TIntermConstantUnion* right = children[1]->getAsConstantUnion();
return left->fold(EOpMul, right);
}
default:
return aggrNode;
}

511
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp vendored Executable file → Normal file
View File

@ -2,7 +2,7 @@
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2016 LunarG, Inc.
// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
@ -51,7 +51,9 @@
// including identifying what extensions are needed if a version does not allow a symbol
//
#include <array>
#include "Initialize.h"
#include "span.h"
namespace glslang {
@ -139,20 +141,17 @@ struct Versioning {
EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECompatibilityProfile);
// Declare pointers to put into the table for versioning.
const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr },
{ EDesktopProfile, 0, 130, 0, nullptr },
{ EBadProfile } };
const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
const std::array Es300Desktop130Version = { Versioning{ EEsProfile, 0, 300, 0, nullptr },
Versioning{ EDesktopProfile, 0, 130, 0, nullptr },
};
const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr },
{ EDesktopProfile, 0, 420, 0, nullptr },
{ EBadProfile } };
const Versioning* Es310Desktop420 = &Es310Desktop420Version[0];
const std::array Es310Desktop400Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr },
Versioning{ EDesktopProfile, 0, 400, 0, nullptr },
};
const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr },
{ EDesktopProfile, 0, 450, 0, nullptr },
{ EBadProfile } };
const Versioning* Es310Desktop450 = &Es310Desktop450Version[0];
const std::array Es310Desktop450Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr },
Versioning{ EDesktopProfile, 0, 450, 0, nullptr },
};
// The main descriptor of what a set of function prototypes can look like, and
// a pointer to extra versioning information, when needed.
@ -162,7 +161,7 @@ struct BuiltInFunction {
int numArguments; // number of arguments (overloads with varying arguments need different entries)
ArgType types; // ArgType mask
ArgClass classes; // the ways this particular function entry manifests
const Versioning* versioning; // nullptr means always a valid version
const span<const Versioning> versioning; // An empty span means always a valid version
};
// The tables can have the same built-in function name more than one time,
@ -174,151 +173,146 @@ struct BuiltInFunction {
//
// Table is terminated by an OpNull TOperator.
const BuiltInFunction BaseFunctions[] = {
const std::array BaseFunctions = {
// TOperator, name, arg-count, ArgType, ArgClass, versioning
// --------- ---- --------- ------- -------- ----------
{ EOpRadians, "radians", 1, TypeF, ClassRegular, nullptr },
{ EOpDegrees, "degrees", 1, TypeF, ClassRegular, nullptr },
{ EOpSin, "sin", 1, TypeF, ClassRegular, nullptr },
{ EOpCos, "cos", 1, TypeF, ClassRegular, nullptr },
{ EOpTan, "tan", 1, TypeF, ClassRegular, nullptr },
{ EOpAsin, "asin", 1, TypeF, ClassRegular, nullptr },
{ EOpAcos, "acos", 1, TypeF, ClassRegular, nullptr },
{ EOpAtan, "atan", 2, TypeF, ClassRegular, nullptr },
{ EOpAtan, "atan", 1, TypeF, ClassRegular, nullptr },
{ EOpPow, "pow", 2, TypeF, ClassRegular, nullptr },
{ EOpExp, "exp", 1, TypeF, ClassRegular, nullptr },
{ EOpLog, "log", 1, TypeF, ClassRegular, nullptr },
{ EOpExp2, "exp2", 1, TypeF, ClassRegular, nullptr },
{ EOpLog2, "log2", 1, TypeF, ClassRegular, nullptr },
{ EOpSqrt, "sqrt", 1, TypeF, ClassRegular, nullptr },
{ EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, nullptr },
{ EOpAbs, "abs", 1, TypeF, ClassRegular, nullptr },
{ EOpSign, "sign", 1, TypeF, ClassRegular, nullptr },
{ EOpFloor, "floor", 1, TypeF, ClassRegular, nullptr },
{ EOpCeil, "ceil", 1, TypeF, ClassRegular, nullptr },
{ EOpFract, "fract", 1, TypeF, ClassRegular, nullptr },
{ EOpMod, "mod", 2, TypeF, ClassLS, nullptr },
{ EOpMin, "min", 2, TypeF, ClassLS, nullptr },
{ EOpMax, "max", 2, TypeF, ClassLS, nullptr },
{ EOpClamp, "clamp", 3, TypeF, ClassLS2, nullptr },
{ EOpMix, "mix", 3, TypeF, ClassLS, nullptr },
{ EOpStep, "step", 2, TypeF, ClassFS, nullptr },
{ EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, nullptr },
{ EOpNormalize, "normalize", 1, TypeF, ClassRegular, nullptr },
{ EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, nullptr },
{ EOpReflect, "reflect", 2, TypeF, ClassRegular, nullptr },
{ EOpRefract, "refract", 3, TypeF, ClassXLS, nullptr },
{ EOpLength, "length", 1, TypeF, ClassRS, nullptr },
{ EOpDistance, "distance", 2, TypeF, ClassRS, nullptr },
{ EOpDot, "dot", 2, TypeF, ClassRS, nullptr },
{ EOpCross, "cross", 2, TypeF, ClassV3, nullptr },
{ EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, nullptr },
{ EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, nullptr },
{ EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, nullptr },
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, nullptr },
{ EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, nullptr },
{ EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, nullptr },
{ EOpAny, "any", 1, TypeB, ClassRSNS, nullptr },
{ EOpAll, "all", 1, TypeB, ClassRSNS, nullptr },
{ EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, nullptr },
{ EOpSinh, "sinh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpCosh, "cosh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpTanh, "tanh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAsinh, "asinh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAcosh, "acosh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAtanh, "atanh", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpAbs, "abs", 1, TypeI, ClassRegular, Es300Desktop130 },
{ EOpSign, "sign", 1, TypeI, ClassRegular, Es300Desktop130 },
{ EOpTrunc, "trunc", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpRound, "round", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, Es300Desktop130 },
{ EOpModf, "modf", 2, TypeF, ClassLO, Es300Desktop130 },
{ EOpMin, "min", 2, TypeIU, ClassLS, Es300Desktop130 },
{ EOpMax, "max", 2, TypeIU, ClassLS, Es300Desktop130 },
{ EOpClamp, "clamp", 3, TypeIU, ClassLS2, Es300Desktop130 },
{ EOpMix, "mix", 3, TypeF, ClassLB, Es300Desktop130 },
{ EOpIsInf, "isinf", 1, TypeF, ClassB, Es300Desktop130 },
{ EOpIsNan, "isnan", 1, TypeF, ClassB, Es300Desktop130 },
{ EOpLessThan, "lessThan", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 },
{ EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 },
{ EOpNull }
BuiltInFunction{ EOpRadians, "radians", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpDegrees, "degrees", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSin, "sin", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpCos, "cos", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpTan, "tan", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAsin, "asin", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAcos, "acos", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAtan, "atan", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAtan, "atan", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpPow, "pow", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpExp, "exp", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpLog, "log", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpExp2, "exp2", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpLog2, "log2", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSqrt, "sqrt", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpAbs, "abs", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpSign, "sign", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFloor, "floor", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpCeil, "ceil", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFract, "fract", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpMod, "mod", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpMin, "min", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpMax, "max", 2, TypeF, ClassLS, {} },
BuiltInFunction{ EOpClamp, "clamp", 3, TypeF, ClassLS2, {} },
BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLS, {} },
BuiltInFunction{ EOpStep, "step", 2, TypeF, ClassFS, {} },
BuiltInFunction{ EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, {} },
BuiltInFunction{ EOpNormalize, "normalize", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpReflect, "reflect", 2, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpRefract, "refract", 3, TypeF, ClassXLS, {} },
BuiltInFunction{ EOpLength, "length", 1, TypeF, ClassRS, {} },
BuiltInFunction{ EOpDistance, "distance", 2, TypeF, ClassRS, {} },
BuiltInFunction{ EOpDot, "dot", 2, TypeF, ClassRS, {} },
BuiltInFunction{ EOpCross, "cross", 2, TypeF, ClassV3, {} },
BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, {} },
BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, {} },
BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, {} },
BuiltInFunction{ EOpAny, "any", 1, TypeB, ClassRSNS, {} },
BuiltInFunction{ EOpAll, "all", 1, TypeB, ClassRSNS, {} },
BuiltInFunction{ EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, {} },
BuiltInFunction{ EOpSinh, "sinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpCosh, "cosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpTanh, "tanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAsinh, "asinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAcosh, "acosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAtanh, "atanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpAbs, "abs", 1, TypeI, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpSign, "sign", 1, TypeI, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpTrunc, "trunc", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpRound, "round", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, {Es300Desktop130Version} },
BuiltInFunction{ EOpModf, "modf", 2, TypeF, ClassLO, {Es300Desktop130Version} },
BuiltInFunction{ EOpMin, "min", 2, TypeIU, ClassLS, {Es300Desktop130Version} },
BuiltInFunction{ EOpMax, "max", 2, TypeIU, ClassLS, {Es300Desktop130Version} },
BuiltInFunction{ EOpClamp, "clamp", 3, TypeIU, ClassLS2, {Es300Desktop130Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLB, {Es300Desktop130Version} },
BuiltInFunction{ EOpIsInf, "isinf", 1, TypeF, ClassB, {Es300Desktop130Version} },
BuiltInFunction{ EOpIsNan, "isnan", 1, TypeF, ClassB, {Es300Desktop130Version} },
BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} },
BuiltInFunction{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeB, ClassRegular, {Es310Desktop450Version} },
BuiltInFunction{ EOpMix, "mix", 3, TypeIU, ClassLB, {Es310Desktop450Version} },
};
const BuiltInFunction DerivativeFunctions[] = {
{ EOpDPdx, "dFdx", 1, TypeF, ClassRegular, nullptr },
{ EOpDPdy, "dFdy", 1, TypeF, ClassRegular, nullptr },
{ EOpFwidth, "fwidth", 1, TypeF, ClassRegular, nullptr },
{ EOpNull }
const std::array DerivativeFunctions = {
BuiltInFunction{ EOpDPdx, "dFdx", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpDPdy, "dFdy", 1, TypeF, ClassRegular, {} },
BuiltInFunction{ EOpFwidth, "fwidth", 1, TypeF, ClassRegular, {} },
};
// For functions declared some other way, but still use the table to relate to operator.
struct CustomFunction {
TOperator op; // operator to map the name to
const char* name; // function name
const Versioning* versioning; // nullptr means always a valid version
const span<const Versioning> versioning; // An empty span means always a valid version
};
const CustomFunction CustomFunctions[] = {
{ EOpBarrier, "barrier", nullptr },
{ EOpMemoryBarrierShared, "memoryBarrierShared", nullptr },
{ EOpGroupMemoryBarrier, "groupMemoryBarrier", nullptr },
{ EOpMemoryBarrier, "memoryBarrier", nullptr },
{ EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr },
{ EOpBarrier, "barrier", {} },
{ EOpMemoryBarrierShared, "memoryBarrierShared", {} },
{ EOpGroupMemoryBarrier, "groupMemoryBarrier", {} },
{ EOpMemoryBarrier, "memoryBarrier", {} },
{ EOpMemoryBarrierBuffer, "memoryBarrierBuffer", {} },
{ EOpPackSnorm2x16, "packSnorm2x16", nullptr },
{ EOpUnpackSnorm2x16, "unpackSnorm2x16", nullptr },
{ EOpPackUnorm2x16, "packUnorm2x16", nullptr },
{ EOpUnpackUnorm2x16, "unpackUnorm2x16", nullptr },
{ EOpPackHalf2x16, "packHalf2x16", nullptr },
{ EOpUnpackHalf2x16, "unpackHalf2x16", nullptr },
{ EOpPackSnorm2x16, "packSnorm2x16", {} },
{ EOpUnpackSnorm2x16, "unpackSnorm2x16", {} },
{ EOpPackUnorm2x16, "packUnorm2x16", {} },
{ EOpUnpackUnorm2x16, "unpackUnorm2x16", {} },
{ EOpPackHalf2x16, "packHalf2x16", {} },
{ EOpUnpackHalf2x16, "unpackHalf2x16", {} },
{ EOpMul, "matrixCompMult", nullptr },
{ EOpOuterProduct, "outerProduct", nullptr },
{ EOpTranspose, "transpose", nullptr },
{ EOpDeterminant, "determinant", nullptr },
{ EOpMatrixInverse, "inverse", nullptr },
{ EOpFloatBitsToInt, "floatBitsToInt", nullptr },
{ EOpFloatBitsToUint, "floatBitsToUint", nullptr },
{ EOpIntBitsToFloat, "intBitsToFloat", nullptr },
{ EOpUintBitsToFloat, "uintBitsToFloat", nullptr },
{ EOpMul, "matrixCompMult", {} },
{ EOpOuterProduct, "outerProduct", {} },
{ EOpTranspose, "transpose", {} },
{ EOpDeterminant, "determinant", {} },
{ EOpMatrixInverse, "inverse", {} },
{ EOpFloatBitsToInt, "floatBitsToInt", {} },
{ EOpFloatBitsToUint, "floatBitsToUint", {} },
{ EOpIntBitsToFloat, "intBitsToFloat", {} },
{ EOpUintBitsToFloat, "uintBitsToFloat", {} },
{ EOpTextureQuerySize, "textureSize", nullptr },
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
{ EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
{ EOpTextureQuerySamples, "textureSamples", nullptr },
{ EOpTexture, "texture", nullptr },
{ EOpTextureProj, "textureProj", nullptr },
{ EOpTextureLod, "textureLod", nullptr },
{ EOpTextureOffset, "textureOffset", nullptr },
{ EOpTextureFetch, "texelFetch", nullptr },
{ EOpTextureFetchOffset, "texelFetchOffset", nullptr },
{ EOpTextureProjOffset, "textureProjOffset", nullptr },
{ EOpTextureLodOffset, "textureLodOffset", nullptr },
{ EOpTextureProjLod, "textureProjLod", nullptr },
{ EOpTextureProjLodOffset, "textureProjLodOffset", nullptr },
{ EOpTextureGrad, "textureGrad", nullptr },
{ EOpTextureGradOffset, "textureGradOffset", nullptr },
{ EOpTextureProjGrad, "textureProjGrad", nullptr },
{ EOpTextureProjGradOffset, "textureProjGradOffset", nullptr },
{ EOpNull }
{ EOpTextureQuerySize, "textureSize", {} },
{ EOpTextureQueryLod, "textureQueryLod", {} },
{ EOpTextureQueryLod, "textureQueryLOD", {} }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", {} },
{ EOpTextureQuerySamples, "textureSamples", {} },
{ EOpTexture, "texture", {} },
{ EOpTextureProj, "textureProj", {} },
{ EOpTextureLod, "textureLod", {} },
{ EOpTextureOffset, "textureOffset", {} },
{ EOpTextureFetch, "texelFetch", {} },
{ EOpTextureFetchOffset, "texelFetchOffset", {} },
{ EOpTextureProjOffset, "textureProjOffset", {} },
{ EOpTextureLodOffset, "textureLodOffset", {} },
{ EOpTextureProjLod, "textureProjLod", {} },
{ EOpTextureProjLodOffset, "textureProjLodOffset", {} },
{ EOpTextureGrad, "textureGrad", {} },
{ EOpTextureGradOffset, "textureGradOffset", {} },
{ EOpTextureProjGrad, "textureProjGrad", {} },
{ EOpTextureProjGradOffset, "textureProjGradOffset", {} },
};
// For the given table of functions, add all the indicated prototypes for each
@ -403,13 +397,13 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function)
bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */)
{
// nullptr means always valid
if (function.versioning == nullptr)
if (function.versioning.empty())
return true;
// check for what is said about our current profile
for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) {
if ((v->profiles & profile) != 0) {
if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version))
for (const auto& v : function.versioning) {
if ((v.profiles & profile) != 0) {
if (v.minCoreVersion <= version || (v.numExtensions > 0 && v.minExtendedVersion <= version))
return true;
}
}
@ -422,12 +416,11 @@ bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile
// called once per stage). This is a performance issue only, not a correctness
// concern. It is done for quality arising from simplicity, as there are subtleties
// to get correct if instead trying to do it surgically.
template<class FunctionT>
void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
template<class FunctionContainer>
void RelateTabledBuiltins(const FunctionContainer& functions, TSymbolTable& symbolTable)
{
while (functions->op != EOpNull) {
symbolTable.relateToOperator(functions->name, functions->op);
++functions;
for (const auto& fn : functions) {
symbolTable.relateToOperator(fn.name, fn.op);
}
}
@ -436,11 +429,10 @@ void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
// Add declarations for all tables of built-in functions.
void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion)
{
const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) {
while (function->op != EOpNull) {
if (ValidVersion(*function, version, profile, spvVersion))
AddTabledBuiltin(decls, *function);
++function;
const auto forEachFunction = [&](TString& decls, const span<const BuiltInFunction>& functions) {
for (const auto& fn : functions) {
if (ValidVersion(fn, version, profile, spvVersion))
AddTabledBuiltin(decls, fn);
}
};
@ -1473,6 +1465,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// NV_shader_atomic_fp16_vector
if (profile != EEsProfile && version >= 430) {
commonBuiltins.append(
"f16vec2 atomicAdd(coherent volatile inout f16vec2, f16vec2);"
"f16vec4 atomicAdd(coherent volatile inout f16vec4, f16vec4);"
"f16vec2 atomicMin(coherent volatile inout f16vec2, f16vec2);"
"f16vec4 atomicMin(coherent volatile inout f16vec4, f16vec4);"
"f16vec2 atomicMax(coherent volatile inout f16vec2, f16vec2);"
"f16vec4 atomicMax(coherent volatile inout f16vec4, f16vec4);"
"f16vec2 atomicExchange(coherent volatile inout f16vec2, f16vec2);"
"f16vec4 atomicExchange(coherent volatile inout f16vec4, f16vec4);"
"\n");
}
if ((profile == EEsProfile && version >= 300) ||
(profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding
commonBuiltins.append(
@ -1726,6 +1732,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"vec4 shadow2DRect(sampler2DRectShadow, vec3);" // GL_ARB_texture_rectangle, caught by keyword check
"vec4 shadow2DRectProj(sampler2DRectShadow, vec4);" // GL_ARB_texture_rectangle, caught by keyword check
"vec4 texture1DArray(sampler1DArray, vec2);" // GL_EXT_texture_array
"vec4 texture2DArray(sampler2DArray, vec3);" // GL_EXT_texture_array
"vec4 shadow1DArray(sampler1DArrayShadow, vec3);" // GL_EXT_texture_array
"vec4 shadow2DArray(sampler2DArrayShadow, vec4);" // GL_EXT_texture_array
"vec4 texture1DArray(sampler1DArray, vec2, float);" // GL_EXT_texture_array
"vec4 texture2DArray(sampler2DArray, vec3, float);" // GL_EXT_texture_array
"vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array
"vec4 texture1DArrayLod(sampler1DArray, vec2, float);" // GL_EXT_texture_array
"vec4 texture2DArrayLod(sampler2DArray, vec3, float);" // GL_EXT_texture_array
"vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array
"\n");
}
}
@ -2097,6 +2113,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"%s subgroupShuffleXor(%s, uint);\n",
"%s subgroupShuffleUp(%s, uint delta);\n",
"%s subgroupShuffleDown(%s, uint delta);\n",
"%s subgroupRotate(%s, uint);\n",
"%s subgroupClusteredRotate(%s, uint, uint);\n",
"%s subgroupAdd(%s);\n",
"%s subgroupMul(%s);\n",
"%s subgroupMin(%s);\n",
@ -2225,6 +2243,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
);
}
// GL_EXT_shader_quad_control
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
commonBuiltins.append(
"bool subgroupQuadAll(bool);\n"
"bool subgroupQuadAny(bool);\n"
);
}
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append(
"bool anyInvocation(bool);"
@ -4105,6 +4132,37 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"u16vec4 unpack16(uint64_t);"
"i32vec2 unpack32(int64_t);"
"u32vec2 unpack32(uint64_t);"
// GL_EXT_expect_assume
"int8_t expectEXT(int8_t, int8_t);"
"i8vec2 expectEXT(i8vec2, i8vec2);"
"i8vec3 expectEXT(i8vec3, i8vec3);"
"i8vec4 expectEXT(i8vec4, i8vec4);"
"uint8_t expectEXT(uint8_t, uint8_t);"
"u8vec2 expectEXT(u8vec2, u8vec2);"
"u8vec3 expectEXT(u8vec3, u8vec3);"
"u8vec4 expectEXT(u8vec4, u8vec4);"
"int16_t expectEXT(int16_t, int16_t);"
"i16vec2 expectEXT(i16vec2, i16vec2);"
"i16vec3 expectEXT(i16vec3, i16vec3);"
"i16vec4 expectEXT(i16vec4, i16vec4);"
"uint16_t expectEXT(uint16_t, uint16_t);"
"u16vec2 expectEXT(u16vec2, u16vec2);"
"u16vec3 expectEXT(u16vec3, u16vec3);"
"u16vec4 expectEXT(u16vec4, u16vec4);"
"int64_t expectEXT(int64_t, int64_t);"
"i64vec2 expectEXT(i64vec2, i64vec2);"
"i64vec3 expectEXT(i64vec3, i64vec3);"
"i64vec4 expectEXT(i64vec4, i64vec4);"
"uint64_t expectEXT(uint64_t, uint64_t);"
"u64vec2 expectEXT(u64vec2, u64vec2);"
"u64vec3 expectEXT(u64vec3, u64vec3);"
"u64vec4 expectEXT(u64vec4, u64vec4);"
"\n");
}
@ -4143,6 +4201,29 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
}
// GL_EXT_expect_assume
if ((profile == EEsProfile && version >= 310) ||
((profile != EEsProfile && version >= 140))) {
commonBuiltins.append(
"void assumeEXT(bool);"
"bool expectEXT(bool, bool);"
"bvec2 expectEXT(bvec2, bvec2);"
"bvec3 expectEXT(bvec3, bvec3);"
"bvec4 expectEXT(bvec4, bvec4);"
"int expectEXT(int, int);"
"ivec2 expectEXT(ivec2, ivec2);"
"ivec3 expectEXT(ivec3, ivec3);"
"ivec4 expectEXT(ivec4, ivec4);"
"uint expectEXT(uint, uint);"
"uvec2 expectEXT(uvec2, uvec2);"
"uvec3 expectEXT(uvec3, uvec3);"
"uvec4 expectEXT(uvec4, uvec4);"
"\n");
}
// QCOM_image_processing
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
@ -4152,6 +4233,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"vec4 textureBoxFilterQCOM(sampler2D, vec2, vec2);"
"vec4 textureBlockMatchSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"vec4 textureBlockMatchSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"vec4 textureBlockMatchWindowSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"vec4 textureBlockMatchWindowSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"vec4 textureBlockMatchGatherSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"vec4 textureBlockMatchGatherSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);"
"\n");
}
@ -4472,6 +4558,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"const int gl_MatrixOperandsSaturatingAccumulation = 0x10;\n"
"const int gl_CooperativeMatrixLayoutRowMajor = 0;\n"
"const int gl_CooperativeMatrixLayoutColumnMajor = 1;\n"
"const int gl_CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202;\n"
"const int gl_CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203;\n"
"\n"
);
}
@ -5246,7 +5334,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangVertex].append(
"int gl_VertexID;" // needs qualifier fixed later
);
if (version >= 140 && spvVersion.vulkan == 0)
if (spvVersion.vulkan == 0)
stageBuiltins[EShLangVertex].append(
"int gl_InstanceID;" // needs qualifier fixed later
);
@ -5301,6 +5389,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangVertex].append(
"highp vec4 gl_Position;" // needs qualifier fixed later
"mediump float gl_PointSize;" // needs qualifier fixed later
"highp int gl_InstanceID;" // needs qualifier fixed later
);
} else {
if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed)
@ -6278,7 +6367,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
{
if ((ms || image) && shadow)
continue;
if (ms && profile != EEsProfile && version < 150)
if (ms && profile != EEsProfile && version < 140)
continue;
if (ms && image && profile == EEsProfile)
continue;
@ -6610,6 +6699,34 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n");
}
// GL_NV_shader_atomic_fp16_vector
if (profile != EEsProfile && version >= 430) {
const int numFp16Builtins = 4;
const char* atomicFp16Func[numFp16Builtins] = {
" imageAtomicAdd(volatile coherent ",
" imageAtomicMin(volatile coherent ",
" imageAtomicMax(volatile coherent ",
" imageAtomicExchange(volatile coherent "
};
const int numFp16DataTypes = 2;
const char* atomicFp16DataTypes[numFp16DataTypes] = {
"f16vec2",
"f16vec4"
};
// Loop twice to add prototypes with/without scope/semantics
for (int j = 0; j < numFp16DataTypes; ++j) {
for (int i = 0; i < numFp16Builtins; ++i) {
commonBuiltins.append(atomicFp16DataTypes[j]);
commonBuiltins.append(atomicFp16Func[i]);
commonBuiltins.append(imageParams);
commonBuiltins.append(", ");
commonBuiltins.append(atomicFp16DataTypes[j]);
commonBuiltins.append(");\n");
}
}
}
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append("float imageAtomicAdd(volatile coherent ");
commonBuiltins.append(imageParams);
@ -7851,6 +7968,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (spvVersion.vulkan == 0) {
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
if (version < 140)
symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_EXT_draw_instanced);
}
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
@ -8002,7 +8121,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
}
// Fall through
// E_GL_EXT_texture_array
if (profile != EEsProfile && spvVersion.spv == 0) {
symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture1DArrayLod", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("texture2DArrayLod", 1, &E_GL_EXT_texture_array);
symbolTable.setFunctionExtensions("shadow1DArrayLod", 1, &E_GL_EXT_texture_array);
}
[[fallthrough]];
case EShLangTessControl:
if (profile == EEsProfile && version >= 310) {
@ -8017,7 +8148,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable);
}
}
// Fall through
[[fallthrough]];
case EShLangTessEvaluation:
case EShLangGeometry:
@ -8603,6 +8734,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable);
}
// GL_EXT_expect_assume
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
symbolTable.setFunctionExtensions("assumeEXT", 1, &E_GL_EXT_expect_assume);
symbolTable.setFunctionExtensions("expectEXT", 1, &E_GL_EXT_expect_assume);
}
// GL_KHR_shader_subgroup
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
@ -8644,6 +8782,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("subgroupShuffleXor", 1, &E_GL_KHR_shader_subgroup_shuffle);
symbolTable.setFunctionExtensions("subgroupShuffleUp", 1, &E_GL_KHR_shader_subgroup_shuffle_relative);
symbolTable.setFunctionExtensions("subgroupShuffleDown", 1, &E_GL_KHR_shader_subgroup_shuffle_relative);
symbolTable.setFunctionExtensions("subgroupRotate", 1, &E_GL_KHR_shader_subgroup_rotate);
symbolTable.setFunctionExtensions("subgroupClusteredRotate", 1, &E_GL_KHR_shader_subgroup_rotate);
symbolTable.setFunctionExtensions("subgroupAdd", 1, &E_GL_KHR_shader_subgroup_arithmetic);
symbolTable.setFunctionExtensions("subgroupMul", 1, &E_GL_KHR_shader_subgroup_arithmetic);
symbolTable.setFunctionExtensions("subgroupMin", 1, &E_GL_KHR_shader_subgroup_arithmetic);
@ -8762,6 +8902,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
}
// GL_EXT_shader_quad_control
if ((profile != EEsProfile && version >= 140) ||
(profile == EEsProfile && version >= 310)) {
symbolTable.setFunctionExtensions("subgroupQuadAll", 1, &E_GL_KHR_shader_subgroup_vote);
symbolTable.setFunctionExtensions("subgroupQuadAny", 1, &E_GL_KHR_shader_subgroup_vote);
}
// GL_EXT_shader_tile_image
symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
@ -8769,10 +8916,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
symbolTable.setFunctionExtensions("textureWeightedQCOM", 1, &E_GL_QCOM_image_processing);
symbolTable.setFunctionExtensions("textureBoxFilterQCOM", 1, &E_GL_QCOM_image_processing);
symbolTable.setFunctionExtensions("textureBlockMatchSADQCOM", 1, &E_GL_QCOM_image_processing);
symbolTable.setFunctionExtensions("textureBlockMatchSSDQCOM", 1, &E_GL_QCOM_image_processing);
symbolTable.setFunctionExtensions("textureBlockMatchWindowSSDQCOM", 1, &E_GL_QCOM_image_processing2);
symbolTable.setFunctionExtensions("textureBlockMatchWindowSADQCOM", 1, &E_GL_QCOM_image_processing2);
symbolTable.setFunctionExtensions("textureBlockMatchGatherSSDQCOM", 1, &E_GL_QCOM_image_processing2);
symbolTable.setFunctionExtensions("textureBlockMatchGatherSADQCOM", 1, &E_GL_QCOM_image_processing2);
}
break;
@ -9058,8 +9211,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable);
BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable);
BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable);
BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable);
BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable);
BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable);
BuiltInVariable("gl_HitKindEXT", EbvHitKind, symbolTable);
BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorld, symbolTable);
@ -9078,6 +9229,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_HitKindFrontFacingMicroTriangleNV", EbvHitKindFrontFacingMicroTriangleNV, symbolTable);
BuiltInVariable("gl_HitKindBackFacingMicroTriangleNV", EbvHitKindBackFacingMicroTriangleNV, symbolTable);
// gl_HitT variables are aliases of their gl_RayTmax counterparts.
RetargetVariable("gl_HitTNV", "gl_RayTmaxNV", symbolTable);
RetargetVariable("gl_HitTEXT", "gl_RayTmaxEXT", symbolTable);
// GL_ARB_shader_ballot
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot);
@ -9695,6 +9850,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("averageRounded", EOpAverageRounded);
symbolTable.relateToOperator("multiply32x16", EOpMul32x16);
symbolTable.relateToOperator("debugPrintfEXT", EOpDebugPrintf);
symbolTable.relateToOperator("assumeEXT", EOpAssumeEXT);
symbolTable.relateToOperator("expectEXT", EOpExpectEXT);
if (PureOperatorBuiltins) {
@ -9898,6 +10055,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("subgroupShuffleXor", EOpSubgroupShuffleXor);
symbolTable.relateToOperator("subgroupShuffleUp", EOpSubgroupShuffleUp);
symbolTable.relateToOperator("subgroupShuffleDown", EOpSubgroupShuffleDown);
symbolTable.relateToOperator("subgroupRotate", EOpSubgroupRotate);
symbolTable.relateToOperator("subgroupClusteredRotate", EOpSubgroupClusteredRotate);
symbolTable.relateToOperator("subgroupAdd", EOpSubgroupAdd);
symbolTable.relateToOperator("subgroupMul", EOpSubgroupMul);
symbolTable.relateToOperator("subgroupMin", EOpSubgroupMin);
@ -9960,12 +10119,35 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj);
}
// GL_EXT_shader_quad_control
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
symbolTable.relateToOperator("subgroupQuadAll", EOpSubgroupQuadAll);
symbolTable.relateToOperator("subgroupQuadAny", EOpSubgroupQuadAny);
}
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {
symbolTable.relateToOperator("textureWeightedQCOM", EOpImageSampleWeightedQCOM);
symbolTable.relateToOperator("textureBoxFilterQCOM", EOpImageBoxFilterQCOM);
symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM);
symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM);
symbolTable.relateToOperator("textureBlockMatchWindowSSDQCOM", EOpImageBlockMatchWindowSSDQCOM);
symbolTable.relateToOperator("textureBlockMatchWindowSADQCOM", EOpImageBlockMatchWindowSADQCOM);
symbolTable.relateToOperator("textureBlockMatchGatherSSDQCOM", EOpImageBlockMatchGatherSSDQCOM);
symbolTable.relateToOperator("textureBlockMatchGatherSADQCOM", EOpImageBlockMatchGatherSADQCOM);
}
if (profile != EEsProfile && spvVersion.spv == 0) {
symbolTable.relateToOperator("texture1DArray", EOpTexture);
symbolTable.relateToOperator("texture2DArray", EOpTexture);
symbolTable.relateToOperator("shadow1DArray", EOpTexture);
symbolTable.relateToOperator("shadow2DArray", EOpTexture);
symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod);
symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod);
symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod);
}
}
@ -10069,7 +10251,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV);
symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV);
} // fallthrough
}
[[fallthrough]];
case EShLangClosestHit:
case EShLangMiss:
if (profile != EEsProfile && version >= 460) {

View File

@ -376,6 +376,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
case EOpNegative:
if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
return nullptr;
break;
default: break; // some compilers want this
}
@ -1277,6 +1278,7 @@ void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, T
// matrix multiply does not change shapes
if (lhsNode->isMatrix() && rhsNode->isMatrix())
return;
[[fallthrough]];
case EOpAdd:
case EOpSub:
case EOpDiv:
@ -2317,6 +2319,40 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
return aggNode;
}
TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right)
{
if (left == nullptr && right == nullptr)
return nullptr;
TIntermAggregate* aggNode = nullptr;
if (left != nullptr)
aggNode = left->getAsAggregate();
if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
aggNode = new TIntermAggregate;
if (left != nullptr)
aggNode->getSequence().push_back(left);
}
TIntermAggregate* rhsagg = right->getAsAggregate();
if (rhsagg == nullptr || rhsagg->getOp() != EOpNull)
aggNode->getSequence().push_back(right);
else
aggNode->getSequence().insert(aggNode->getSequence().end(),
rhsagg->getSequence().begin(),
rhsagg->getSequence().end());
return aggNode;
}
TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
{
TIntermAggregate* aggNode = mergeAggregate(left, right);
if (aggNode)
aggNode->setLoc(loc);
return aggNode;
}
//
// Turn an existing node into an aggregate.
//
@ -2590,6 +2626,18 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
{
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
int exponent = 0;
frexp(d, &exponent);
int minExp = baseType == EbtFloat ? -126 : -14;
int maxExp = baseType == EbtFloat ? 127 : 15;
if (exponent > maxExp) { //overflow, d = inf
d = std::numeric_limits<double>::infinity();
} else if (exponent < minExp) { //underflow, d = 0.0;
d = 0.0;
}
}
TConstUnionArray unionArray(1);
unionArray[0].setDConst(d);
@ -2647,28 +2695,42 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
// a valid part of the dereference chain.
//
// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
// 'bufferReferenceOk' says if type is buffer_reference, the routine will stop to find the most left node.
//
// 'proc' is an optional function to run on each node that is processed during the traversal. 'proc' must
// return true to continue the traversal, or false to end the traversal early.
//
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
const TIntermTyped* TIntermediate::traverseLValueBase(const TIntermTyped* node, bool swizzleOkay,
bool bufferReferenceOk,
std::function<bool(const TIntermNode&)> proc)
{
do {
const TIntermBinary* binary = node->getAsBinaryNode();
if (binary == nullptr)
if (binary == nullptr) {
if (proc) {
proc(*node);
}
return node;
}
TOperator op = binary->getOp();
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle &&
op != EOpMatrixSwizzle)
return nullptr;
if (! swizzleOkay) {
if (!swizzleOkay) {
if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
return nullptr;
if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
(binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
! binary->getLeft()->getType().isArray())
!binary->getLeft()->getType().isArray())
return nullptr;
}
node = node->getAsBinaryNode()->getLeft();
if (proc) {
if (!proc(*node)) {
return node;
}
}
node = binary->getLeft();
if (bufferReferenceOk && node->isReference())
return node;
} while (true);
@ -2795,10 +2857,9 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag
//}
if (language == EShLangVertex) {
// the names won't be found in the symbol table unless the versions are right,
// so version logic does not need to be repeated here
addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
if ((version < 140 && requestedExtensions.find(E_GL_EXT_draw_instanced) != requestedExtensions.end()) || version >= 140)
addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
}
// Add a child to the root node for the linker objects
@ -3430,6 +3491,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
// check for non-Boolean operands
if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
return false;
break;
default:
break;
@ -3473,13 +3535,14 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
if (left->getType() == right->getType())
return true;
// Fall through
[[fallthrough]];
case EOpMul:
case EOpMulAssign:
// At least the basic type has to match
if (left->getBasicType() != right->getBasicType())
return false;
break;
default:
break;
@ -3622,7 +3685,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
case EOpAssign:
if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
return false;
// fall through
[[fallthrough]];
case EOpAdd:
case EOpSub:

View File

@ -59,7 +59,7 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);
infoSink.info.prefix(prefix);
infoSink.info.location(loc);
infoSink.info.location(loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
if (prefix == EPrefixError) {
@ -208,7 +208,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
//
// If we get here, we have an error and a message.
//
const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
if (symNode)
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
@ -234,7 +234,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
const TIntermSymbol* symNode = node->getAsSymbolNode();
if (node->getQualifier().isWriteOnly()) {
const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
if (symNode != nullptr)
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
@ -257,6 +257,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
case EOpVectorSwizzle:
case EOpMatrixSwizzle:
rValueErrorCheck(loc, op, binaryNode->getLeft());
break;
default:
break;
}
@ -722,6 +723,24 @@ void TParseContextBase::finish()
if (parsingBuiltins)
return;
for (const TString& relaxedSymbol : relaxedSymbols)
{
TSymbol* symbol = symbolTable.find(relaxedSymbol);
TType& type = symbol->getWritableType();
for (const TTypeLoc& typeLoc : *type.getStruct())
{
if (typeLoc.type->isOpaque())
{
typeLoc.type->getSampler() = TSampler{};
typeLoc.type->setBasicType(EbtInt);
TString fieldName("/*");
fieldName.append(typeLoc.type->getFieldName());
fieldName.append("*/");
typeLoc.type->setFieldName(fieldName);
}
}
}
// Transfer the linkage symbols to AST nodes, preserving order.
TIntermAggregate* linkage = new TIntermAggregate;
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)

View File

@ -4,6 +4,7 @@
// Copyright (C) 2015-2018 Google, Inc.
// Copyright (C) 2017, 2019 ARM Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
// Modifications Copyright (C) 2024 Ravi Prakash Singh.
//
// All rights reserved.
//
@ -41,7 +42,6 @@
#include "Initialize.h"
#include "Scan.h"
#include "../OSDependent/osinclude.h"
#include <algorithm>
#include "preprocessor/PpContext.h"
@ -399,6 +399,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
if (spvVersion.spv < glslang::EShTargetSpv_1_3)
error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", "");
intermediate.setUseVariablePointers();
} else if (spvVersion.spv > 0 && tokens[0].compare("use_replicated_composites") == 0) {
if (tokens.size() != 1)
error(loc, "extra tokens", "#pragma", "");
intermediate.setReplicatedComposites();
} else if (tokens[0].compare("once") == 0) {
warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0) {
@ -492,7 +496,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
if ((variable->getMangledName() == "gl_PrimitiveTriangleIndicesEXT" && primitiveType != ElgTriangles) ||
(variable->getMangledName() == "gl_PrimitiveLineIndicesEXT" && primitiveType != ElgLines) ||
(variable->getMangledName() == "gl_PrimitivePointIndicesEXT" && primitiveType != ElgPoints)) {
error(loc, "cannot be used (ouput primitive type mismatch)", string->c_str(), "");
error(loc, "cannot be used (output primitive type mismatch)", string->c_str(), "");
variable = nullptr;
}
}
@ -598,6 +602,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
indexValue >= resources.maxCullDistances) {
error(loc, "gl_CullDistance", "[", "array index out of range '%d'", indexValue);
}
else if (base->getQualifier().builtIn == EbvSampleMask &&
indexValue >= (resources.maxSamples + 31) / 32) {
error(loc, "gl_SampleMask", "[", "array index out of range '%d'", indexValue);
}
// For 2D per-view builtin arrays, update the inner dimension size in parent type
if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
TIntermBinary* binaryNode = base->getAsBinaryNode();
@ -632,7 +640,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
else {
// input/output blocks either don't exist or can't be variably indexed
}
} else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
} else if (language == EShLangFragment && base->getQualifier().isPipeOutput() && base->getQualifier().builtIn != EbvSampleMask)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
else if (base->getBasicType() == EbtSampler && version >= 130) {
const char* explanation = "variable indexing sampler array";
@ -993,17 +1001,25 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
break;
}
}
if (fieldFound) {
if (base->getType().getQualifier().isFrontEndConstant())
result = intermediate.foldDereference(base, member, loc);
else {
blockMemberExtensionCheck(loc, base, member, field);
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[member].type);
if ((*fields)[member].type->getQualifier().isIo())
intermediate.addIoAccessed(field);
if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed)
result = vkRelaxedRemapDotDereference(loc, *base, *(*fields)[member].type, field);
if (result == base)
{
if (base->getType().getQualifier().isFrontEndConstant())
result = intermediate.foldDereference(base, member, loc);
else {
blockMemberExtensionCheck(loc, base, member, field);
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[member].type);
if ((*fields)[member].type->getQualifier().isIo())
intermediate.addIoAccessed(field);
}
}
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
} else {
auto baseSymbol = base;
@ -1343,6 +1359,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
// - a user function.
// Error check for a function requiring specific extensions present.
if (builtIn &&
(fnCandidate->getBuiltInOp() == EOpSubgroupQuadAll || fnCandidate->getBuiltInOp() == EOpSubgroupQuadAny))
requireExtensions(loc, 1, &E_GL_EXT_shader_quad_control, fnCandidate->getName().c_str());
if (builtIn && fnCandidate->getNumExtensions())
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
@ -1352,7 +1372,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage");
if (builtIn && fnCandidate->getType().contains8BitInt())
requireInt8Arithmetic(loc, "built-in function", "(u)int8 types can only be in uniform block or buffer storage");
if (builtIn && (fnCandidate->getBuiltInOp() == EOpTextureFetch || fnCandidate->getBuiltInOp() == EOpTextureQuerySize)) {
if ((*fnCandidate)[0].type->getSampler().isMultiSample() && version <= 140)
requireExtensions(loc, 1, &E_GL_ARB_texture_multisample, fnCandidate->getName().c_str());
}
if (arguments != nullptr) {
// Make sure qualifications work for these arguments.
TIntermAggregate* aggregate = arguments->getAsAggregate();
@ -1655,7 +1678,9 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
}
} else {
if (value->getType().isTexture() || value->getType().isImage()) {
if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
if (spvVersion.spv != 0)
error(loc, "sampler or image cannot be used as return type when generating SPIR-V", "return", "");
else if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
error(loc, "sampler or image can be used as return type only when the extension GL_ARB_bindless_texture enabled", "return", "");
}
branch = intermediate.addBranch(EOpReturn, value, loc);
@ -1746,6 +1771,11 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
name == "gl_MeshPrimitivesNV") {
length = getIoArrayImplicitSize(type.getQualifier());
}
} else if (const auto typed = intermNode->getAsTyped()) {
if (typed->getQualifier().builtIn == EbvSampleMask) {
requireProfile(loc, EEsProfile, "the array size of gl_SampleMask and gl_SampleMaskIn is ceil(gl_MaxSamples/32)");
length = (resources.maxSamples + 31) / 32;
}
}
if (length == 0) {
if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
@ -2502,15 +2532,26 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
error(loc, "only supported on image with format r64i", fnCandidate.getName().c_str(), "");
else if (callNode.getType().getBasicType() == EbtUint64 && imageType.getQualifier().getFormat() != ElfR64ui)
error(loc, "only supported on image with format r64ui", fnCandidate.getName().c_str(), "");
} else if(callNode.getType().getBasicType() == EbtFloat16 &&
((callNode.getType().getVectorSize() == 2 && arg0->getType().getQualifier().getFormat() == ElfRg16f) ||
(callNode.getType().getVectorSize() == 4 && arg0->getType().getQualifier().getFormat() == ElfRgba16f))) {
if (StartsWith(fnCandidate.getName(), "imageAtomicAdd") ||
StartsWith(fnCandidate.getName(), "imageAtomicExchange") ||
StartsWith(fnCandidate.getName(), "imageAtomicMin") ||
StartsWith(fnCandidate.getName(), "imageAtomicMax")) {
requireExtensions(loc, 1, &E_GL_NV_shader_atomic_fp16_vector, fnCandidate.getName().c_str());
} else {
error(loc, "f16vec2/4 operation not supported on: ", fnCandidate.getName().c_str(), "");
}
} else if (imageType.getSampler().type == EbtFloat) {
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0) {
if (StartsWith(fnCandidate.getName(), "imageAtomicExchange")) {
// imageAtomicExchange doesn't require an extension
} else if ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
(fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
(fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0)) {
} else if (StartsWith(fnCandidate.getName(), "imageAtomicAdd") ||
StartsWith(fnCandidate.getName(), "imageAtomicLoad") ||
StartsWith(fnCandidate.getName(), "imageAtomicStore")) {
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
} else if ((fnCandidate.getName().compare(0, 14, "imageAtomicMin") == 0) ||
(fnCandidate.getName().compare(0, 14, "imageAtomicMax") == 0)) {
} else if (StartsWith(fnCandidate.getName(), "imageAtomicMin") ||
StartsWith(fnCandidate.getName(), "imageAtomicMax")) {
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
} else {
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
@ -2560,6 +2601,11 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
E_GL_EXT_shader_atomic_int64 };
requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) &&
arg0->getType().getBasicType() == EbtFloat16 &&
(arg0->getType().getVectorSize() == 2 || arg0->getType().getVectorSize() == 4 )) {
requireExtensions(loc, 1, &E_GL_NV_shader_atomic_fp16_vector, fnCandidate.getName().c_str());
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
(arg0->getType().getBasicType() == EbtFloat ||
arg0->getType().getBasicType() == EbtDouble)) {
@ -2571,7 +2617,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
}
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
const TIntermTyped* base = TIntermediate::traverseLValueBase(arg0, true, true);
const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
"atomic memory functions.";
if (base) {
@ -2591,20 +2637,57 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
case EOpInterpolateAtCentroid:
case EOpInterpolateAtSample:
case EOpInterpolateAtOffset:
case EOpInterpolateAtVertex:
// Make sure the first argument is an interpolant, or an array element of an interpolant
case EOpInterpolateAtVertex: {
if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
// It might still be an array element.
// Traverse down the left branch of arg0 to ensure this argument is a valid interpolant.
//
// We could check more, but the semantics of the first argument are already met; the
// only way to turn an array into a float/vec* is array dereference and swizzle.
// For desktop GL >4.3 we effectively only need to ensure that arg0 represents an l-value from an
// input declaration.
//
// ES and desktop 4.3 and earlier: swizzles may not be used
// desktop 4.4 and later: swizzles may be used
bool swizzleOkay = (!isEsProfile()) && (version >= 440);
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
// For desktop GL <= 4.3 and ES, we must also ensure that swizzling is not used
//
// For ES, we must also ensure that a field selection operator (i.e., '.') is not used on a named
// struct.
const bool esProfile = isEsProfile();
const bool swizzleOkay = !esProfile && (version >= 440);
std::string interpolantErrorMsg = "first argument must be an interpolant, or interpolant-array element";
bool isValid = true; // Assume that the interpolant is valid until we find a condition making it invalid
bool isIn = false; // Checks whether or not the interpolant is a shader input
bool structAccessOp = false; // Whether or not the previous node in the chain is a struct accessor
TIntermediate::traverseLValueBase(
arg0, swizzleOkay, false,
[&isValid, &isIn, &interpolantErrorMsg, esProfile, &structAccessOp](const TIntermNode& n) -> bool {
auto* type = n.getAsTyped();
if (type) {
if (type->getType().getQualifier().storage == EvqVaryingIn) {
isIn = true;
}
// If a field accessor was used, it can only be used to access a field with an input block, not a struct.
if (structAccessOp && (type->getType().getBasicType() != EbtBlock)) {
interpolantErrorMsg +=
". Using the field of a named struct as an interpolant argument is not "
"allowed (ES-only).";
isValid = false;
}
}
// ES has different requirements for interpolants than GL
if (esProfile) {
// Swizzling will be taken care of by the 'swizzleOkay' argument passsed to traverseLValueBase,
// so we only ned to check whether or not a field accessor has been used with a named struct.
auto* binary = n.getAsBinaryNode();
if (binary && (binary->getOp() == EOpIndexDirectStruct)) {
structAccessOp = true;
}
}
// Don't continue traversing if we know we have an invalid interpolant at this point.
return isValid;
});
if (!isIn || !isValid) {
error(loc, interpolantErrorMsg.c_str(), fnCandidate.getName().c_str(), "");
}
}
if (callNode.getOp() == EOpInterpolateAtVertex) {
@ -2620,12 +2703,12 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
}
}
}
break;
} break;
case EOpEmitStreamVertex:
case EOpEndStreamPrimitive:
if (version == 150)
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the version is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
intermediate.setMultiStream();
break;
@ -3534,6 +3617,19 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
makeSpecConst = ! intArgument && !type.isArray();
break;
case EOpConstructCooperativeMatrixNV:
case EOpConstructCooperativeMatrixKHR:
case EOpConstructStruct:
{
const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites };
if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) {
makeSpecConst = true;
} else {
makeSpecConst = false;
}
}
break;
default:
// anything else wasn't white-listed in the spec as a conversion
makeSpecConst = false;
@ -3839,6 +3935,18 @@ void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, con
}
void TParseContext::hitObjectNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier)
{
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtHitObjectNV)) {
error(loc, "struct is not allowed to contain hitObjectNV:", type.getTypeName().c_str(), identifier.c_str());
} else if (type.getBasicType() == EbtHitObjectNV) {
TStorageQualifier qualifier = type.getQualifier().storage;
if (qualifier != EvqGlobal && qualifier != EvqTemporary) {
error(loc, "hitObjectNV can only be declared in global or function scope with no storage qualifier:", "hitObjectNV", identifier.c_str());
}
}
}
void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (parsingBuiltins)
@ -3931,6 +4039,18 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
// Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
if (!isMemberCheck || structNestingLevel > 0)
invariantCheck(loc, qualifier);
if (qualifier.isFullQuads()) {
if (qualifier.storage != EvqVaryingIn)
error(loc, "can only apply to input layout", "full_quads ", "");
intermediate.setReqFullQuadsMode();
}
if (qualifier.isQuadDeriv()) {
if (qualifier.storage != EvqVaryingIn)
error(loc, "can only apply to input layout", "quad_derivatives", "");
intermediate.setQuadDerivMode();
}
}
//
@ -4191,8 +4311,8 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
dst.spirvStorageClass = src.spirvStorageClass;
// SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
if (src.hasSprivDecorate()) {
if (dst.hasSprivDecorate()) {
if (src.hasSpirvDecorate()) {
if (dst.hasSpirvDecorate()) {
const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
for (auto& decorate : srcSpirvDecorate.decorates) {
@ -5804,6 +5924,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.layoutOverrideCoverage = true;
return;
}
if (id == "full_quads")
{
const char* feature = "full_quads qualifier";
requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
publicType.qualifier.layoutFullQuads = true;
return;
}
}
if (language == EShLangVertex ||
language == EShLangTessControl ||
@ -5853,6 +5982,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
return;
}
if (id == "quad_derivatives")
{
const char* feature = "quad_derivatives qualifier";
requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
publicType.qualifier.layoutQuadDeriv = true;
return;
}
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
}
@ -6154,7 +6293,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "needs a literal integer", "max_primitives", "");
return;
}
// Fall through
[[fallthrough]];
case EShLangTask:
// Fall through
@ -6281,6 +6420,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
if (src.layoutShaderRecord)
dst.layoutShaderRecord = true;
if (src.layoutFullQuads)
dst.layoutFullQuads = true;
if (src.layoutQuadDeriv)
dst.layoutQuadDeriv = true;
if (src.layoutBindlessSampler)
dst.layoutBindlessSampler = true;
if (src.layoutBindlessImage)
@ -6326,8 +6469,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
switch (qualifier.storage) {
case EvqVaryingIn:
case EvqVaryingOut:
if (!type.getQualifier().isTaskMemory() &&
!type.getQualifier().hasSprivDecorate() &&
if (!type.getQualifier().isTaskMemory() && !type.getQualifier().hasSpirvDecorate() &&
(type.getBasicType() != EbtBlock ||
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
@ -6455,10 +6597,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
if (repeated >= 0 && ! typeCollision)
error(loc, "overlapping use of location", "location", "%d", repeated);
// "fragment-shader outputs/tileImageEXT ... if two variables are placed within the same
// location, they must have the same underlying type (floating-point or integer)"
if (typeCollision && language == EShLangFragment && (qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated);
// When location aliasing, the aliases sharing the location must have the same underlying numerical type and bit width(
// floating - point or integer, 32 - bit versus 64 - bit,etc.)
if (typeCollision && (qualifier.isPipeInput() || qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
error(loc, "the aliases sharing the location", "location", "%d must be the same basic type and interpolation qualification", repeated);
}
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
@ -7227,7 +7369,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T
realFunc.addParameter(TParameter().copyParam((*function)[i]));
}
TParameter tmpP = { nullptr, &uintType };
TParameter tmpP = { nullptr, &uintType, {} };
realFunc.addParameter(TParameter().copyParam(tmpP));
arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(1, loc, true));
@ -7244,7 +7386,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T
realFunc.addParameter(TParameter().copyParam((*function)[i]));
}
TParameter tmpP = { nullptr, &uintType };
TParameter tmpP = { nullptr, &uintType, {} };
realFunc.addParameter(TParameter().copyParam(tmpP));
arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(-1, loc, true));
@ -7256,7 +7398,7 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T
}
} else if (function->getName() == "atomicCounter") {
// change atomicCounter into a direct read of the variable
if (arguments->getAsTyped()) {
if (arguments && arguments->getAsTyped()) {
result = arguments->getAsTyped();
}
}
@ -7304,6 +7446,7 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub
case EbtUint:
case EbtUint8:
case EbtUint16:
case EbtSpirvType:
break;
default:
error(loc, "coopmat invalid basic type", TType::getBasicString(publicType.typeParameters->basicType), "");
@ -7321,12 +7464,14 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub
}
}
bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&,
bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType,
TArraySizes*, TIntermTyped* initializer, TType& type)
{
vkRelaxedRemapUniformMembers(loc, publicType, type, identifier);
if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() ||
type.getQualifier().storage != EvqUniform ||
!(type.containsNonOpaque()|| type.getBasicType() == EbtAtomicUint)) {
!(type.containsNonOpaque() || type.getBasicType() == EbtAtomicUint || (type.containsSampler() && type.isStruct()))) {
return false;
}
@ -7400,6 +7545,263 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString
return true;
}
template <typename Function>
static void ForEachOpaque(const TType& type, const TString& path, Function callback)
{
auto recursion = [&callback](const TType& type, const TString& path, bool skipArray, auto& recursion) -> void {
if (!skipArray && type.isArray())
{
std::vector<int> indices(type.getArraySizes()->getNumDims());
for (int flatIndex = 0;
flatIndex < type.getArraySizes()->getCumulativeSize();
++flatIndex)
{
TString subscriptPath = path;
for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
{
int index = indices[dimIndex];
subscriptPath.append("[");
subscriptPath.append(String(index));
subscriptPath.append("]");
}
recursion(type, subscriptPath, true, recursion);
for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
{
++indices[dimIndex];
if (indices[dimIndex] < type.getArraySizes()->getDimSize(dimIndex))
break;
else
indices[dimIndex] = 0;
}
}
}
else if (type.isStruct() && type.containsOpaque())
{
const TTypeList& types = *type.getStruct();
for (const TTypeLoc& typeLoc : types)
{
TString nextPath = path;
nextPath.append(".");
nextPath.append(typeLoc.type->getFieldName());
recursion(*(typeLoc.type), nextPath, false, recursion);
}
}
else if (type.isOpaque())
{
callback(type, path);
}
};
recursion(type, path, false, recursion);
}
void TParseContext::vkRelaxedRemapUniformMembers(const TSourceLoc& loc, const TPublicType& publicType, const TType& type,
const TString& identifier)
{
if (!type.isStruct() || !type.containsOpaque())
return;
ForEachOpaque(type, identifier,
[&publicType, &loc, this](const TType& type, const TString& path) {
TArraySizes arraySizes = {};
if (type.getArraySizes()) arraySizes = *type.getArraySizes();
TTypeParameters typeParameters = {};
if (type.getTypeParameters()) typeParameters = *type.getTypeParameters();
TPublicType memberType{};
memberType.basicType = type.getBasicType();
memberType.sampler = type.getSampler();
memberType.qualifier = type.getQualifier();
memberType.vectorSize = type.getVectorSize();
memberType.matrixCols = type.getMatrixCols();
memberType.matrixRows = type.getMatrixRows();
memberType.coopmatNV = type.isCoopMatNV();
memberType.coopmatKHR = type.isCoopMatKHR();
memberType.arraySizes = nullptr;
memberType.userDef = nullptr;
memberType.loc = loc;
memberType.typeParameters = (type.getTypeParameters() ? &typeParameters : nullptr);
memberType.spirvType = nullptr;
memberType.qualifier.storage = publicType.qualifier.storage;
memberType.shaderQualifiers = publicType.shaderQualifiers;
TString& structMemberName = *NewPoolTString(path.c_str()); // A copy is required due to declareVariable() signature.
declareVariable(loc, structMemberName, memberType, nullptr, nullptr);
});
}
void TParseContext::vkRelaxedRemapFunctionParameter(TFunction* function, TParameter& param, std::vector<int>* newParams)
{
function->addParameter(param);
if (!param.type->isStruct() || !param.type->containsOpaque())
return;
ForEachOpaque(*param.type, (param.name ? *param.name : param.type->getFieldName()),
[function, param, newParams](const TType& type, const TString& path) {
TString* memberName = NewPoolTString(path.c_str());
TType* memberType = new TType();
memberType->shallowCopy(type);
memberType->getQualifier().storage = param.type->getQualifier().storage;
memberType->clearArraySizes();
TParameter memberParam = {};
memberParam.name = memberName;
memberParam.type = memberType;
memberParam.defaultValue = nullptr;
function->addParameter(memberParam);
if (newParams)
newParams->push_back(function->getParamCount()-1);
});
}
//
// Generates a valid GLSL dereferencing string for the input TIntermNode
//
struct AccessChainTraverser : public TIntermTraverser {
AccessChainTraverser() : TIntermTraverser(false, false, true)
{}
TString path = "";
TStorageQualifier topLevelStorageQualifier = TStorageQualifier::EvqLast;
bool visitBinary(TVisit, TIntermBinary* binary) override {
if (binary->getOp() == EOpIndexDirectStruct)
{
const TTypeList& members = *binary->getLeft()->getType().getStruct();
const TTypeLoc& member =
members[binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()];
TString memberName = member.type->getFieldName();
if (path != "")
path.append(".");
path.append(memberName);
}
if (binary->getOp() == EOpIndexDirect)
{
const TConstUnionArray& indices = binary->getRight()->getAsConstantUnion()->getConstArray();
for (int index = 0; index < indices.size(); ++index)
{
path.append("[");
path.append(String(indices[index].getIConst()));
path.append("]");
}
}
return true;
}
void visitSymbol(TIntermSymbol* symbol) override {
if (symbol->getType().isOpaque())
topLevelStorageQualifier = symbol->getQualifier().storage;
if (!IsAnonymous(symbol->getName()))
path.append(symbol->getName());
}
};
TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc, TFunction* function, TIntermTyped* intermTyped)
{
AccessChainTraverser accessChainTraverser{};
intermTyped->traverse(&accessChainTraverser);
if (accessChainTraverser.topLevelStorageQualifier == TStorageQualifier::EvqUniform)
{
TParameter param = { 0, new TType, {} };
param.type->shallowCopy(intermTyped->getType());
function->addParameter(param);
return intermTyped;
}
TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType, {} };
param.type->shallowCopy(intermTyped->getType());
std::vector<int> newParams = {};
vkRelaxedRemapFunctionParameter(function, param, &newParams);
if (intermTyped->getType().isOpaque())
{
TIntermNode* remappedArgument = intermTyped;
{
TIntermSymbol* intermSymbol = nullptr;
TSymbol* symbol = symbolTable.find(*param.name);
if (symbol && symbol->getAsVariable())
intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
else
{
TVariable* variable = new TVariable(param.name, *param.type);
intermSymbol = intermediate.addSymbol(*variable, loc);
}
remappedArgument = intermSymbol;
}
return remappedArgument;
}
else if (!(intermTyped->isStruct() && intermTyped->getType().containsOpaque()))
return intermTyped;
else
{
TIntermNode* remappedArgument = intermTyped;
{
TSymbol* symbol = symbolTable.find(*param.name);
if (symbol && symbol->getAsVariable())
remappedArgument = intermediate.addSymbol(*symbol->getAsVariable(), loc);
}
if (!newParams.empty())
remappedArgument = intermediate.makeAggregate(remappedArgument, loc);
for (int paramIndex : newParams)
{
TParameter& newParam = function->operator[](paramIndex);
TIntermSymbol* intermSymbol = nullptr;
TSymbol* symbol = symbolTable.find(*newParam.name);
if (symbol && symbol->getAsVariable())
intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
else
{
TVariable* variable = new TVariable(newParam.name, *newParam.type);
intermSymbol = intermediate.addSymbol(*variable, loc);
}
remappedArgument = intermediate.growAggregate(remappedArgument, intermSymbol);
}
return remappedArgument;
}
}
TIntermTyped* TParseContext::vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped& base, const TType& member,
const TString& identifier)
{
if (!member.isOpaque())
return &base;
AccessChainTraverser traverser{};
base.traverse(&traverser);
if (!traverser.path.empty())
traverser.path.append(".");
traverser.path.append(identifier);
const TSymbol* symbol = symbolTable.find(traverser.path);
if (!symbol)
return &base;
TIntermTyped* result = intermediate.addSymbol(*symbol->getAsVariable());
result->setType(symbol->getType());
return result;
}
//
// Do everything necessary to handle a variable (non-block) declaration.
// Either redeclaring a variable, or making a new one, updating the symbol
@ -7439,7 +7841,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
error(loc, "unexpected number type parameters", identifier.c_str(), "");
}
if (publicType.typeParameters) {
if (!isTypeFloat(publicType.typeParameters->basicType) && !isTypeInt(publicType.typeParameters->basicType)) {
if (!isTypeFloat(publicType.typeParameters->basicType) &&
!isTypeInt(publicType.typeParameters->basicType) && publicType.typeParameters->basicType != EbtSpirvType) {
error(loc, "expected 8, 16, 32, or 64 bit signed or unsigned integer or 16, 32, or 64 bit float type", identifier.c_str(), "");
}
}
@ -7483,6 +7886,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
transparentOpaqueCheck(loc, type, identifier);
atomicUintCheck(loc, type, identifier);
accStructCheck(loc, type, identifier);
hitObjectNVCheck(loc, type, identifier);
checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
if (type.getQualifier().storage == EvqConst && type.containsReference()) {
error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", "");
@ -7981,6 +8385,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
int paramCount = 0; // keeps track of the constructor parameter number being checked
// We don't know "top down" whether type is a specialization constant,
// but a const becomes a specialization constant if any of its children are.
bool hasSpecConst = false;
bool isConstConstructor = true;
// for each parameter to the constructor call, check to see if the right type is passed or convert them
// to the right type if possible (and allowed).
// for structure constructors, just check if the right type is passed, no conversion is allowed.
@ -7993,13 +8402,24 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
else
newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
if (newNode)
if (newNode) {
*p = newNode;
else
if (!newNode->getType().getQualifier().isConstant())
isConstConstructor = false;
if (newNode->getType().getQualifier().isSpecConstant())
hasSpecConst = true;
} else
return nullptr;
}
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
TIntermTyped* ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites };
if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) {
if (isConstConstructor && hasSpecConst) {
ret_node->getWritableType().getQualifier().makeSpecConstant();
}
}
TIntermAggregate *agg_node = ret_node->getAsAggregate();
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
@ -8078,6 +8498,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructUVec2, false, newSrcNode, type);
return newNode;
}
[[fallthrough]];
case EOpConstructUVec3:
case EOpConstructUVec4:
case EOpConstructUint:
@ -8099,6 +8520,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
intermediate.addBuiltInFunctionCall(node->getLoc(), EOpPackUint2x32, true, node, type);
return newNode;
}
[[fallthrough]];
case EOpConstructDVec2:
case EOpConstructDVec3:
case EOpConstructDVec4:
@ -8129,9 +8551,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
case EOpConstructF16Mat4x4:
case EOpConstructFloat16:
basicOp = EOpConstructFloat16;
// 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
// 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types,
// so construct a 32-bit type and convert
if (!intermediate.getArithemeticFloat16Enabled()) {
// and do not generate any conversion if it is an identity conversion, i.e. float16_t(<float16_t> var)
if (!intermediate.getArithemeticFloat16Enabled() && (node->getBasicType() != EbtFloat16)) {
TType tempType(EbtFloat, EvqTemporary, type.getVectorSize());
newNode = node;
if (tempType != newNode->getType()) {
@ -8152,9 +8575,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
case EOpConstructI8Vec4:
case EOpConstructInt8:
basicOp = EOpConstructInt8;
// 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
// 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types,
// so construct a 32-bit type and convert
if (!intermediate.getArithemeticInt8Enabled()) {
// and do not generate any conversion if it is an identity conversion, i.e. int8_t(<int8_t> var)
if (!intermediate.getArithemeticInt8Enabled() && (node->getBasicType() != EbtInt8)) {
TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
newNode = node;
if (tempType != newNode->getType()) {
@ -8175,9 +8599,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
case EOpConstructU8Vec4:
case EOpConstructUint8:
basicOp = EOpConstructUint8;
// 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
// 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types,
// so construct a 32-bit type and convert
if (!intermediate.getArithemeticInt8Enabled()) {
// and do not generate any conversion if it is an identity conversion, i.e. uint8_t(<uint8_t> var)
if (!intermediate.getArithemeticInt8Enabled() && (node->getBasicType() != EbtUint8)) {
TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
newNode = node;
if (tempType != newNode->getType()) {
@ -8198,9 +8623,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
case EOpConstructI16Vec4:
case EOpConstructInt16:
basicOp = EOpConstructInt16;
// 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
// 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types,
// so construct a 32-bit type and convert
if (!intermediate.getArithemeticInt16Enabled()) {
// and do not generate any conversion if it is an identity conversion, i.e. int16_t(<int16_t> var)
if (!intermediate.getArithemeticInt16Enabled() && (node->getBasicType() != EbtInt16)) {
TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
newNode = node;
if (tempType != newNode->getType()) {
@ -8221,9 +8647,10 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
case EOpConstructU16Vec4:
case EOpConstructUint16:
basicOp = EOpConstructUint16;
// 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
// 8/16-bit storage extensions don't support direct constructing composites of 8/16-bit types,
// so construct a 32-bit type and convert
if (!intermediate.getArithemeticInt16Enabled()) {
// and do not generate any conversion if it is an identity conversion, i.e. uint16_t(<uint16_t> var)
if (!intermediate.getArithemeticInt16Enabled() && (node->getBasicType() != EbtUint16)) {
TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
newNode = node;
if (tempType != newNode->getType()) {
@ -8251,7 +8678,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type);
return newNode;
}
// fall through
[[fallthrough]];
case EOpConstructU64Vec2:
case EOpConstructU64Vec3:
case EOpConstructU64Vec4:
@ -8540,7 +8967,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
memberQualifier.storage = EvqtaskPayloadSharedEXT;
if (memberQualifier.storage == EvqSpirvStorageClass)
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
if (memberQualifier.hasSpirvDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
@ -9316,7 +9743,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
break;
}
// Fall through
[[fallthrough]];
case ElgPoints:
case ElgLineStrip:
case ElgTriangleStrip:

View File

@ -180,6 +180,7 @@ public:
// Basic parsing state, easily accessible to the grammar
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
TVector<TString> relaxedSymbols;
int statementNestingLevel; // 0 if outside all flow control or compound statements
int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // 0 if outside structures
@ -367,6 +368,10 @@ public:
TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
// returns true if the variable was remapped to something else
bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
void vkRelaxedRemapUniformMembers(const TSourceLoc&, const TPublicType&, const TType&, const TString&);
void vkRelaxedRemapFunctionParameter(TFunction*, TParameter&, std::vector<int>* newParams = nullptr);
TIntermNode* vkRelaxedRemapFunctionArgument(const TSourceLoc&, TFunction*, TIntermTyped*);
TIntermTyped* vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped&, const TType&, const TString&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
@ -392,6 +397,7 @@ public:
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
void hitObjectNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
void memberQualifierCheck(glslang::TPublicType&);
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false, const TPublicType* publicType = nullptr);

View File

@ -35,14 +35,21 @@
#include "../Include/Common.h"
#include "../Include/PoolAlloc.h"
// Mostly here for target that do not support threads such as WASI.
#ifdef DISABLE_THREAD_SUPPORT
#define THREAD_LOCAL
#else
#define THREAD_LOCAL thread_local
#endif
namespace glslang {
namespace {
thread_local TPoolAllocator* threadPoolAllocator = nullptr;
THREAD_LOCAL TPoolAllocator* threadPoolAllocator = nullptr;
TPoolAllocator* GetDefaultThreadPoolAllocator()
{
thread_local TPoolAllocator defaultAllocator;
THREAD_LOCAL TPoolAllocator defaultAllocator;
return &defaultAllocator;
}
} // anonymous namespace

View File

@ -1496,6 +1496,12 @@ int TScanContext::tokenizeIdentifier()
case USAMPLERCUBE:
case USAMPLER2DARRAY:
afterType = true;
if (keyword == SAMPLER2DARRAY || keyword == SAMPLER2DARRAYSHADOW) {
if (!parseContext.isEsProfile() &&
(parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
return keyword;
}
}
return nonreservedKeyword(300, 130);
case SAMPLER3D:
@ -1539,6 +1545,12 @@ int TScanContext::tokenizeIdentifier()
case USAMPLER1D:
case USAMPLER1DARRAY:
afterType = true;
if (keyword == SAMPLER1DARRAYSHADOW) {
if (!parseContext.isEsProfile() &&
(parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
return keyword;
}
}
return es30ReservedFromGLSL(130);
case ISAMPLER2DRECT:
case USAMPLER2DRECT:
@ -1608,7 +1620,9 @@ int TScanContext::tokenizeIdentifier()
if (parseContext.isEsProfile() && parseContext.version == 300)
reservedWord();
else if ((parseContext.isEsProfile() && parseContext.version < 300) ||
(!parseContext.isEsProfile() && parseContext.version < 130))
((!parseContext.isEsProfile() && parseContext.version < 130) &&
!parseContext.symbolTable.atBuiltInLevel() &&
!parseContext.extensionTurnedOn(E_GL_EXT_texture_array)))
return identifierOrType();
return keyword;

View File

@ -58,7 +58,6 @@
#endif
#include "../Include/ShHandle.h"
#include "../../OGLCompilersDLL/InitializeDll.h"
#include "preprocessor/PpContext.h"
@ -83,7 +82,10 @@ namespace { // anonymous namespace for file-local functions and symbols
int NumberOfClients = 0;
// global initialization lock
#ifndef DISABLE_THREAD_SUPPORT
std::mutex init_lock;
#endif
using namespace glslang;
@ -421,7 +423,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
TInfoSink infoSink;
// Make sure only one thread tries to do this at a time
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
// See if it's already been done for this version/profile combination
int versionIndex = MapVersionToIndex(version);
@ -634,6 +638,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
version = profile == EEsProfile ? 320 : 450;
}
break;
default:
break;
}
@ -788,7 +793,7 @@ bool ProcessDeferred(
// set version/profile to defaultVersion/defaultProfile regardless of the #version
// directive in the source code
bool forceDefaultVersionAndProfile,
int overrideVersion, // overrides version specified by #verison or default version
int overrideVersion, // overrides version specified by #version or default version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate, // returned tree, etc.
@ -1311,10 +1316,9 @@ bool CompileDeferred(
//
int ShInitialize()
{
if (! InitProcess())
return 0;
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
++NumberOfClients;
if (PerProcessGPA == nullptr)
@ -1335,9 +1339,6 @@ int ShInitialize()
ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/)
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, 0));
return reinterpret_cast<void*>(base);
@ -1345,9 +1346,6 @@ ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unus
ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/)
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, 0));
return reinterpret_cast<void*>(base);
@ -1355,9 +1353,6 @@ ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions un
ShHandle ShConstructUniformMap()
{
if (!InitThread())
return nullptr;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
return reinterpret_cast<void*>(base);
@ -1383,7 +1378,9 @@ void ShDestruct(ShHandle handle)
//
int ShFinalize()
{
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
--NumberOfClients;
assert(NumberOfClients >= 0);
if (NumberOfClients > 0)
@ -1446,7 +1443,8 @@ int ShCompile(
int /*debugOptions*/,
int defaultVersion, // use 100 for ES environment, 110 for desktop
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages // warnings/errors/AST; things to print out
EShMessages messages, // warnings/errors/AST; things to print out,
const char *shaderFileName // the filename
)
{
// Map the generic handle to the C++ object
@ -1462,6 +1460,9 @@ int ShCompile(
compiler->infoSink.info.erase();
compiler->infoSink.debug.erase();
compiler->infoSink.info.setShaderFileName(shaderFileName);
compiler->infoSink.debug.setShaderFileName(shaderFileName);
TIntermediate intermediate(compiler->getLanguage());
TShader::ForbidIncluder includer;
@ -1857,6 +1858,9 @@ void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setG
void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); }
void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); }
void TShader::addSourceText(const char* text, size_t len) { intermediate->addSourceText(text, len); }
void TShader::setSourceFile(const char* file) { intermediate->setSourceFile(file); }
#ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
@ -1871,8 +1875,6 @@ void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlatt
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages messages, Includer& includer)
{
if (! InitThread())
return false;
SetThreadPoolAllocator(pool);
if (! preamble)
@ -1897,8 +1899,6 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
std::string* output_string,
Includer& includer)
{
if (! InitThread())
return false;
SetThreadPoolAllocator(pool);
if (! preamble)
@ -2117,11 +2117,15 @@ const char* TProgram::getInfoDebugLog()
// Reflection implementation.
//
unsigned int TObjectReflection::layoutLocation() const { return type->getQualifier().layoutLocation; }
bool TProgram::buildReflection(int opts)
{
if (! linked || reflection != nullptr)
return false;
SetThreadPoolAllocator(pool);
int firstStage = EShLangVertex, lastStage = EShLangFragment;
if (opts & EShReflectionIntermediateIO) {
@ -2177,6 +2181,9 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
{
if (! linked)
return false;
SetThreadPoolAllocator(pool);
TIoMapper* ioMapper = nullptr;
TIoMapper defaultIOMapper;
if (pIoMapper == nullptr)

View File

@ -149,6 +149,7 @@ void TType::buildMangledName(TString& mangledName) const
mangledName += '-';
(*structure)[i].type->buildMangledName(mangledName);
}
break;
default:
break;
}

View File

@ -1,7 +1,7 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2013 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Copyright (C) 2015-2020 Google, Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
@ -235,6 +235,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_KHR_shader_subgroup_ballot] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_rotate] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
extensionBehavior[E_GL_KHR_memory_scope_semantics] = EBhDisable;
@ -258,14 +259,20 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
extensionBehavior[E_GL_EXT_maximal_reconvergence] = EBhDisable;
extensionBehavior[E_GL_EXT_fragment_shader_barycentric] = EBhDisable;
extensionBehavior[E_GL_EXT_expect_assume] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable;
extensionBehavior[E_GL_EXT_spec_constant_composites] = EBhDisable;
extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
extensionBehavior[E_GL_ARB_shading_language_include] = EBhDisable;
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
@ -302,12 +309,14 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable;
extensionBehavior[E_GL_NV_shader_invocation_reorder] = EBhDisable;
extensionBehavior[E_GL_NV_displacement_micromap] = EBhDisable;
extensionBehavior[E_GL_NV_shader_atomic_fp16_vector] = EBhDisable;
// ARM
extensionBehavior[E_GL_ARM_shader_core_builtins] = EBhDisable;
// QCOM
extensionBehavior[E_GL_QCOM_image_processing] = EBhDisable;
extensionBehavior[E_GL_QCOM_image_processing2] = EBhDisable;
// AEP
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
@ -356,9 +365,12 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
extensionBehavior[E_GL_EXT_mesh_shader] = EBhDisable;
extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_quad_control] = EBhDisable;
extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
extensionBehavior[E_GL_EXT_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_array] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@ -436,6 +448,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_QCOM_image_processing 1\n"
"#define GL_QCOM_image_processing2 1\n"
;
if (version >= 300) {
@ -444,6 +457,7 @@ void TParseVersions::getPreamble(std::string& preamble)
if (version >= 310) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
preamble += "#define GL_EXT_maximal_reconvergence 1\n";
}
} else { // !isEsProfile()
@ -487,7 +501,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_vertex_attrib_64bit 1\n"
"#define GL_ARB_draw_instanced 1\n"
"#define GL_ARB_fragment_coord_conventions 1\n"
"#define GL_ARB_bindless_texture 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
@ -506,6 +520,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 1\n"
"#define GL_EXT_shader_integer_mix 1\n"
"#define GL_EXT_spec_constant_composites 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
@ -561,6 +576,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_invocation_reorder 1\n"
"#define GL_QCOM_image_processing 1\n"
"#define GL_QCOM_image_processing2 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
@ -580,8 +596,16 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_atomic_float2 1\n"
"#define GL_EXT_fragment_shader_barycentric 1\n"
"#define GL_EXT_shader_quad_control 1\n"
"#define GL_EXT_texture_array 1\n"
"#define GL_EXT_control_flow_attributes2 1\n"
;
if (spvVersion.spv == 0) {
preamble += "#define GL_ARB_bindless_texture 1\n";
}
if (version >= 150) {
// define GL_core_profile and GL_compatibility_profile
preamble += "#define GL_core_profile 1\n";
@ -592,6 +616,7 @@ void TParseVersions::getPreamble(std::string& preamble)
if (version >= 140) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
preamble += "#define GL_EXT_maximal_reconvergence 1\n";
}
if (version >= 130) {
preamble +="#define GL_FRAGMENT_PRECISION_HIGH 1\n";
@ -750,8 +775,8 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int
for (int i = 0; i < numExtensions; ++i) {
switch (getExtensionBehavior(extensions[i])) {
case EBhWarn:
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
// fall through
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
[[fallthrough]];
case EBhRequire:
case EBhEnable:
okay = true;
@ -788,7 +813,8 @@ void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int
error(loc, "deprecated, may be removed in future release", featureDesc, "");
else if (! suppressWarnings())
infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
String(depVersion) + "; may be removed in future release").c_str(), loc);
String(depVersion) + "; may be removed in future release").c_str(),
loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
}
}
}
@ -825,11 +851,14 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte
for (int i = 0; i < numExtensions; ++i) {
TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
if (behavior == EBhDisable && relaxedErrors()) {
infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc);
infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc,
messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
behavior = EBhWarn;
}
if (behavior == EBhWarn) {
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
infoSink.info.message(EPrefixWarning,
("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(),
loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
warned = true;
}
}
@ -968,6 +997,8 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
else if (strcmp(extension, "GL_ARB_shading_language_include") == 0)
updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
// subgroup_* to subgroup_basic
else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0)
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);

13
3rdparty/glslang/glslang/MachineIndependent/Versions.h vendored Executable file → Normal file
View File

@ -1,7 +1,7 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2013 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Copyright (C) 2015-2018 Google, Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
@ -171,6 +171,7 @@ const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_sub
const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot";
const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle";
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
const char* const E_GL_KHR_shader_subgroup_rotate = "GL_KHR_shader_subgroup_rotate";
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics";
@ -215,6 +216,13 @@ const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intr
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap";
const char* const E_GL_EXT_shader_quad_control = "GL_EXT_shader_quad_control";
const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced";
const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array";
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume";
const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2";
const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites";
// Arrays of extensions for the above viewportEXTs duplications
@ -235,6 +243,7 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi
// #line and #include
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
const char* const E_GL_ARB_shading_language_include = "GL_ARB_shading_language_include";
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
@ -272,6 +281,7 @@ const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer
const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder";
const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch";
const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap";
const char* const E_GL_NV_shader_atomic_fp16_vector = "GL_NV_shader_atomic_fp16_vector";
// ARM
const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins";
@ -283,6 +293,7 @@ const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing";
const char* const E_GL_QCOM_image_processing2 = "GL_QCOM_image_processing2";
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";

View File

@ -125,6 +125,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
return EatSubgroupUniformControlFlow;
else if (name == "export")
return EatExport;
else if (name == "maximally_reconverges")
return EatMaximallyReconverges;
else
return EatNone;
}
@ -360,6 +362,10 @@ void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttri
requireExtensions(loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
intermediate.setSubgroupUniformControlFlow();
break;
case EatMaximallyReconverges:
requireExtensions(loc, 1, &E_GL_EXT_maximal_reconvergence, "attribute");
intermediate.setMaximallyReconverges();
break;
default:
warn(loc, "attribute does not apply to a function", "", "");
break;

View File

@ -121,6 +121,7 @@ namespace glslang {
EatNonReadable,
EatSubgroupUniformControlFlow,
EatExport,
EatMaximallyReconverges,
};
class TIntermAggregate;

View File

@ -110,13 +110,6 @@ using namespace glslang;
%{
/* windows only pragma */
#ifdef _MSC_VER
#pragma warning(disable : 4065)
#pragma warning(disable : 4127)
#pragma warning(disable : 4244)
#endif
#define parseContext (*pParseContext)
#define yyerror(context, msg) context->parserError(msg)
@ -492,18 +485,44 @@ function_call_header_no_parameters
function_call_header_with_parameters
: function_call_header assignment_expression {
TParameter param = { 0, new TType };
param.type->shallowCopy($2->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = $2;
if (parseContext.spvVersion.vulkan > 0
&& parseContext.spvVersion.vulkanRelaxed
&& $2->getType().containsOpaque())
{
$$.intermNode = parseContext.vkRelaxedRemapFunctionArgument($$.loc, $1.function, $2);
$$.function = $1.function;
}
else
{
TParameter param = { 0, new TType, {} };
param.type->shallowCopy($2->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = $2;
}
}
| function_call_header_with_parameters COMMA assignment_expression {
TParameter param = { 0, new TType };
param.type->shallowCopy($3->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
if (parseContext.spvVersion.vulkan > 0
&& parseContext.spvVersion.vulkanRelaxed
&& $3->getType().containsOpaque())
{
TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument($2.loc, $1.function, $3);
if (remappedNode == $3)
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
else
$$.intermNode = parseContext.intermediate.mergeAggregate($1.intermNode, remappedNode, $2.loc);
$$.function = $1.function;
}
else
{
TParameter param = { 0, new TType, {} };
param.type->shallowCopy($3->getType());
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
}
}
;
@ -948,18 +967,24 @@ function_prototype
$$.function = $1;
if (parseContext.compileOnly) $$.function->setExport();
$$.loc = $2.loc;
const char * extensions[2] = { E_GL_EXT_subgroup_uniform_control_flow, E_GL_EXT_maximal_reconvergence };
parseContext.requireExtensions($2.loc, 2, extensions, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
if (parseContext.compileOnly) $$.function->setExport();
$$.loc = $3.loc;
const char * extensions[2] = { E_GL_EXT_subgroup_uniform_control_flow, E_GL_EXT_maximal_reconvergence };
parseContext.requireExtensions($3.loc, 2, extensions, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
if (parseContext.compileOnly) $$.function->setExport();
$$.loc = $3.loc;
const char * extensions[2] = { E_GL_EXT_subgroup_uniform_control_flow, E_GL_EXT_maximal_reconvergence };
parseContext.requireExtensions($3.loc, 2, extensions, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1);
parseContext.handleFunctionAttributes($3.loc, *$4);
}
@ -980,7 +1005,12 @@ function_header_with_parameters
// Add the parameter
$$ = $1;
if ($2.param.type->getBasicType() != EbtVoid)
$1->addParameter($2.param);
{
if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
$1->addParameter($2.param);
else
parseContext.vkRelaxedRemapFunctionParameter($1, $2.param);
}
else
delete $2.param.type;
}
@ -998,7 +1028,10 @@ function_header_with_parameters
} else {
// Add the parameter
$$ = $1;
$1->addParameter($3.param);
if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
$1->addParameter($3.param);
else
parseContext.vkRelaxedRemapFunctionParameter($1, $3.param);
}
}
;
@ -1038,7 +1071,7 @@ parameter_declarator
}
parseContext.reservedErrorCheck($2.loc, *$2.string);
TParameter param = {$2.string, new TType($1)};
TParameter param = {$2.string, new TType($1), {}};
$$.loc = $2.loc;
$$.param = param;
}
@ -1056,7 +1089,7 @@ parameter_declarator
parseContext.arraySizeRequiredCheck($3.loc, *$3.arraySizes);
parseContext.reservedErrorCheck($2.loc, *$2.string);
TParameter param = { $2.string, type };
TParameter param = { $2.string, type, {} };
$$.loc = $2.loc;
$$.param = param;
@ -1109,7 +1142,7 @@ parameter_declaration
parameter_type_specifier
: type_specifier {
TParameter param = { 0, new TType($1) };
TParameter param = { 0, new TType($1), {} };
$$.param = param;
if ($1.arraySizes)
parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes);
@ -1726,6 +1759,7 @@ type_parameter_specifier_list
: type_specifier {
$$ = new TTypeParameters;
$$->arraySizes = new TArraySizes;
$$->spirvType = $1.spirvType;
$$->basicType = $1.basicType;
}
| unary_expression {
@ -3549,11 +3583,17 @@ precision_qualifier
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($5, *$2.string);
parseContext.structArrayCheck($2.loc, *structure);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct");
else if (parseContext.spvVersion.vulkanRelaxed
&& structure->containsOpaque())
parseContext.relaxedSymbols.push_back(structure->getTypeName());
$$.init($1.loc);
$$.basicType = EbtStruct;
$$.userDef = structure;
@ -3914,7 +3954,8 @@ iteration_statement
$$ = $1;
}
| attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
const char * extensions[2] = { E_GL_EXT_control_flow_attributes, E_GL_EXT_control_flow_attributes2 };
parseContext.requireExtensions($2->getLoc(), 2, extensions, "attribute");
parseContext.handleLoopAttributes(*$1, $2);
$$ = $2;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2016 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
@ -565,6 +565,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break;
case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break;
case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break;
case EOpSubgroupRotate: out.debug << "subgroupRotate"; break;
case EOpSubgroupClusteredRotate: out.debug << "subgroupClusteredRotate"; break;
case EOpSubgroupAdd: out.debug << "subgroupAdd"; break;
case EOpSubgroupMul: out.debug << "subgroupMul"; break;
case EOpSubgroupMin: out.debug << "subgroupMin"; break;
@ -597,6 +599,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
case EOpSubgroupQuadAll: out.debug << "subgroupQuadAll"; break;
case EOpSubgroupQuadAny: out.debug << "subgroupQuadAny"; break;
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
@ -1000,6 +1004,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break;
case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break;
case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break;
case EOpSubgroupRotate: out.debug << "subgroupRotate"; break;
case EOpSubgroupClusteredRotate: out.debug << "subgroupClusteredRotate"; break;
case EOpSubgroupAdd: out.debug << "subgroupAdd"; break;
case EOpSubgroupMul: out.debug << "subgroupMul"; break;
case EOpSubgroupMin: out.debug << "subgroupMin"; break;
@ -1032,6 +1038,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
case EOpSubgroupQuadAll: out.debug << "subgroupQuadAll"; break;
case EOpSubgroupQuadAny: out.debug << "subgroupQuadAny"; break;
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
@ -1208,12 +1216,12 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
// - shows all digits, no premature rounding
static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
{
if (IsInfinity(value)) {
if (std::isinf(value)) {
if (value < 0)
out.debug << "-1.#INF";
else
out.debug << "+1.#INF";
} else if (IsNan(value))
} else if (std::isnan(value))
out.debug << "1.#IND";
else {
const int maxSize = 340;
@ -1512,6 +1520,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
if (getSubgroupUniformControlFlow())
infoSink.debug << "subgroup_uniform_control_flow\n";
if (getMaximallyReconverges())
infoSink.debug << "maximally_reconverges\n";
switch (language) {
case EShLangVertex:
break;
@ -1576,7 +1587,7 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
infoSink.debug << "max_vertices = " << vertices << "\n";
infoSink.debug << "max_primitives = " << primitives << "\n";
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
// Fall through
[[fallthrough]];
case EShLangTask:
// Fall through
case EShLangCompute:

View File

@ -39,6 +39,7 @@
#include "gl_types.h"
#include "iomapper.h"
#include "LiveTraverser.h"
#include "SymbolTable.h"
//
@ -60,6 +61,108 @@
namespace glslang {
struct TVarEntryInfo {
long long id;
TIntermSymbol* symbol;
bool live;
bool upgradedToPushConstant;
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
upgradedToPushConstant = false;
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
};
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
}
TVarLivePair(const TVarLivePair& src) : pair(src) { }
};
typedef std::vector<TVarLivePair> TVarLiveVector;
class TVarGatherTraverser : public TLiveTraverser {
public:
TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
@ -85,7 +188,7 @@ public:
addGlobalReference(base->getAccessName());
if (target) {
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
TVarEntryInfo ent = {base->getId(), base, ! traverseAll, {}, {}, {}, {}, {}, {}, {}};
ent.stage = intermediate.getStage();
TVarLiveMap::iterator at = target->find(
ent.symbol->getAccessName()); // std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
@ -124,7 +227,7 @@ public:
else
return;
TVarEntryInfo ent = { base->getId() };
TVarEntryInfo ent = { base->getId(), {}, {}, {}, {}, {}, {}, {}, {}, {} };
// Fix a defect, when block has no instance name, we need to find its block name
TVarLiveMap::const_iterator at = source->find(base->getAccessName());
if (at == source->end())
@ -176,7 +279,7 @@ struct TNotifyInOutAdaptor
{
EShLanguage stage;
TIoMapResolver& resolver;
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
: stage(s)
, resolver(r)
{
@ -866,7 +969,7 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
}
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
return ent.newLocation = -1;
}
@ -953,7 +1056,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
return ent.newLocation = type.getQualifier().layoutLocation;
}
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
if (type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -1497,6 +1600,36 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
return !hadError;
}
TGlslIoMapper::TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(intermediates, 0, sizeof(TIntermediate*) * EShLangCount);
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
TGlslIoMapper::~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
// Map I/O variables to provided offsets, and make bindings for
// unbound but live variables.
//

View File

@ -37,7 +37,6 @@
#define _IOMAPPER_INCLUDED
#include <cstdint>
#include "LiveTraverser.h"
#include <unordered_map>
#include <unordered_set>
//
@ -49,84 +48,7 @@ class TInfoSink;
namespace glslang {
class TIntermediate;
struct TVarEntryInfo {
long long id;
TIntermSymbol* symbol;
bool live;
bool upgradedToPushConstant;
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
upgradedToPushConstant = false;
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
};
struct TVarEntryInfo;
// Base class for shared TIoMapResolver services, used by several derivations.
struct TDefaultIoResolverBase : public glslang::TIoMapResolver {
public:
@ -267,29 +189,6 @@ protected:
typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
}
TVarLivePair(const TVarLivePair& src) : pair(src) { }
};
typedef std::vector<TVarLivePair> TVarLiveVector;
// I/O mapper
class TIoMapper {
public:
@ -303,34 +202,8 @@ public:
// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
TGlslIoMapper();
virtual ~TGlslIoMapper();
// If set, the uniform block with the given name will be changed to be backed by
// push_constant if it's size is <= maxSize
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
@ -341,8 +214,6 @@ public:
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
TIntermediate* intermediates[EShLangCount];
bool hadError = false;
EProfile profile;
@ -352,6 +223,8 @@ private:
TString autoPushConstantBlockName;
unsigned int autoPushConstantMaxSize;
TLayoutPacking autoPushConstantBlockPacking;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
};
} // end namespace glslang

View File

@ -113,6 +113,28 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
}
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
return // 1) same stage and same shader interface
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
// 2) accross stages and both are uniform or buffer
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
// 3) in/out matched across stage boundary
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
}
static bool isSameSymbol(TIntermSymbol* symbol1, EShLanguage stage1, TIntermSymbol* symbol2, EShLanguage stage2) {
// If they are both blocks in the same shader interface,
// match by the block-name, not the identifier name.
if (symbol1->getType().getBasicType() == EbtBlock && symbol2->getType().getBasicType() == EbtBlock) {
if (isSameInterface(symbol1, stage1, symbol2, stage2)) {
return symbol1->getType().getTypeName() == symbol2->getType().getTypeName();
}
} else if (symbol1->getName() == symbol2->getName())
return true;
return false;
}
//
// do error checking on the shader boundary in / out vars
//
@ -137,7 +159,32 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
// do matching and error checking
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
// TODO: final check; make sure that any statically used `in` have matching `out` written to
// Check that all of our inputs have matching outputs from the previous stage.
// Only do this for Vulkan, since GL_ARB_separate_shader_objects allows for
// the in/out to not match
if (spvVersion.vulkan > 0) {
for (auto& nextStageInterm : unitLinkerObjects) {
auto* nextStageSymbol = nextStageInterm->getAsSymbolNode();
bool found = false;
for (auto& curStageInterm : linkerObjects) {
if (isSameSymbol(curStageInterm->getAsSymbolNode(), getStage(), nextStageSymbol, unit.getStage())) {
found = true;
break;
}
}
if (!found) {
TString errmsg;
errmsg.append("Input '");
if (nextStageSymbol->getType().getBasicType() == EbtBlock)
errmsg.append(nextStageSymbol->getType().getTypeName());
else
errmsg.append(nextStageSymbol->getName());
errmsg.append("' in ").append(StageName(unit.getStage()));
errmsg.append(" shader has no corresponding output in ").append(StageName(getStage())).append(" shader.");
error(infoSink, errmsg.c_str(), unit.getStage());
}
}
}
}
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
@ -511,17 +558,6 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c
globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
}
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
return // 1) same stage and same shader interface
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
// 2) accross stages and both are uniform or buffer
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
// 3) in/out matched across stage boundary
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
}
//
// Global Unfiform block stores any default uniforms (i.e. uniforms without a block)
// If two linked stages declare the same member, they are meant to be the same uniform
@ -707,24 +743,18 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
// Error check and merge the linker objects (duplicates should not be created)
std::size_t initialNumLinkerObjects = linkerObjects.size();
for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
bool merge = true;
// Don't merge inputs backwards into previous stages
if (getStage() != unitStage && unitSymbol->getQualifier().storage == EvqVaryingIn)
merge = false;
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
bool isSameSymbol = false;
// If they are both blocks in the same shader interface,
// match by the block-name, not the identifier name.
if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) {
if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
}
}
else if (symbol->getName() == unitSymbol->getName())
isSameSymbol = true;
if (isSameSymbol) {
if (isSameSymbol(symbol, getStage(), unitSymbol, unitStage)) {
// filter out copy
merge = false;
@ -1350,7 +1380,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
if (primitives == TQualifier::layoutNotSet)
error(infoSink, "At least one shader must specify a layout(max_primitives = value)");
// fall through
[[fallthrough]];
case EShLangTask:
if (numTaskNVBlocks > 1)
error(infoSink, "Only one taskNV interface block is allowed per shader");
@ -1689,7 +1719,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// First range:
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
TRange componentRange(0, 3);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions
collision = checkLocationRange(set, range, type, typeCollision);
@ -1699,7 +1729,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// Second range:
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
TRange componentRange2(0, 1);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions
collision = checkLocationRange(set, range2, type, typeCollision);
@ -1725,7 +1755,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
TBasicType basicTy = type.getBasicType();
if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
basicTy = type.getSampler().type;
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0);
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions, except for vertex inputs on desktop targeting OpenGL
if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
@ -1737,6 +1767,24 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
return collision;
}
// Check that two types can be stored in different components in the same location.
// They must be the same type, except signed/unsigned integers are considered compatible.
static bool checkCompatibleTypes(TBasicType t1, TBasicType t2) {
if (t1 != t2) {
if ((t1 == EbtInt8 && t2 == EbtUint8) ||
(t2 == EbtInt8 && t1 == EbtUint8) ||
(t1 == EbtInt16 && t2 == EbtUint16) ||
(t2 == EbtInt16 && t1 == EbtUint16)||
(t1 == EbtInt && t2 == EbtUint) ||
(t2 == EbtInt && t1 == EbtUint)||
(t1 == EbtInt64 && t2 == EbtUint64) ||
(t2 == EbtInt64 && t1 == EbtUint64)) {
return true;
}
}
return t1 == t2;
}
// Compare a new (the passed in) 'range' against the existing set, and see
// if there are any collisions.
//
@ -1748,7 +1796,13 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
if (range.overlap(usedIo[set][r])) {
// there is a collision; pick one
return std::max(range.location.start, usedIo[set][r].location.start);
} else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
} else if (range.location.overlap(usedIo[set][r].location) &&
(!checkCompatibleTypes(type.getBasicType(), usedIo[set][r].basicType) ||
type.getQualifier().centroid != usedIo[set][r].centroid ||
type.getQualifier().smooth != usedIo[set][r].smooth ||
type.getQualifier().flat != usedIo[set][r].flat ||
type.getQualifier().sample != usedIo[set][r].sample ||
type.getQualifier().patch != usedIo[set][r].patch)) {
// aliased-type mismatch
typeCollision = true;
return std::max(range.location.start, usedIo[set][r].location.start);
@ -2217,9 +2271,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
}
// To aid the basic HLSL rule about crossing vec4 boundaries.
bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
bool TIntermediate::improperStraddle(const TType& type, int size, int offset, bool vectorLike)
{
if (! type.isVector() || type.isArray())
if (! vectorLike || type.isArray())
return false;
return size <= 16 ? offset / 16 != (offset + size - 1) / 16

View File

@ -43,11 +43,12 @@
#include "../Public/ShaderLang.h"
#include "Versions.h"
#include <algorithm>
#include <array>
#include <functional>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <array>
class TInfoSink;
@ -98,7 +99,8 @@ private:
// A "call" is a pair: <caller, callee>.
// There can be duplicates. General assumption is the list is small.
struct TCall {
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
TCall(const TString& pCaller, const TString& pCallee)
: caller(pCaller), callee(pCallee), visited(false), currentPath(false), errorGiven(false) { }
TString caller;
TString callee;
bool visited;
@ -122,8 +124,10 @@ struct TRange {
// within the same location range, component range, and index value. Locations don't alias unless
// all other dimensions of their range overlap.
struct TIoRange {
TIoRange(TRange location, TRange component, TBasicType basicType, int index)
: location(location), component(component), basicType(basicType), index(index) { }
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat, bool sample, bool patch)
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat), sample(sample), patch(patch)
{
}
bool overlap(const TIoRange& rhs) const
{
return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index;
@ -132,6 +136,11 @@ struct TIoRange {
TRange component;
TBasicType basicType;
int index;
bool centroid;
bool smooth;
bool flat;
bool sample;
bool patch;
};
// An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying
@ -344,10 +353,12 @@ public:
needToLegalize(false),
binaryDoubleOutput(false),
subgroupUniformControlFlow(false),
maximallyReconverges(false),
usePhysicalStorageBuffer(false),
spirvRequirement(nullptr),
spirvExecutionMode(nullptr),
uniformLocationBase(0)
uniformLocationBase(0),
quadDerivMode(false), reqFullQuadsMode(false)
{
localSize[0] = 1;
localSize[1] = 1;
@ -527,6 +538,8 @@ public:
TOperator mapTypeToConstructorOp(const TType&) const;
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* makeAggregate(TIntermNode* node);
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
TIntermAggregate* makeAggregate(const TSourceLoc&);
@ -572,7 +585,8 @@ public:
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
// Tree ops
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
static const TIntermTyped* traverseLValueBase(const TIntermTyped*, bool swizzleOkay, bool bufferReferenceOk = false,
std::function<bool(const TIntermNode&)> proc = {});
// Linkage related
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
@ -718,6 +732,11 @@ public:
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setReplicatedComposites()
{
useReplicatedComposites = true;
}
bool usingReplicatedComposites() const { return useReplicatedComposites; }
void setUseVariablePointers()
{
useVariablePointers = true;
@ -853,6 +872,10 @@ public:
void setXfbMode() { xfbMode = true; }
bool getXfbMode() const { return xfbMode; }
void setQuadDerivMode(bool mode = true) { quadDerivMode = mode; }
bool getQuadDerivMode() const { return quadDerivMode; }
void setReqFullQuadsMode(bool mode = true) { reqFullQuadsMode = mode; }
bool getReqFullQuadsMode() const { return reqFullQuadsMode; }
void setMultiStream() { multiStream = true; }
bool isMultiStream() const { return multiStream; }
bool setOutputPrimitive(TLayoutGeometry p)
@ -959,6 +982,9 @@ public:
void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
void setMaximallyReconverges() { maximallyReconverges = true; }
bool getMaximallyReconverges() const { return maximallyReconverges; }
// GL_EXT_spirv_intrinsics
void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
@ -1044,7 +1070,7 @@ public:
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
static bool improperStraddle(const TType& type, int size, int offset);
static bool improperStraddle(const TType& type, int size, int offset, bool vectorLike);
static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize);
static int getOffset(const TType& type, int index);
static int getBlockSize(const TType& blockType);
@ -1222,7 +1248,9 @@ protected:
bool needToLegalize;
bool binaryDoubleOutput;
bool subgroupUniformControlFlow;
bool maximallyReconverges;
bool usePhysicalStorageBuffer;
bool useReplicatedComposites { false };
TSpirvRequirement* spirvRequirement;
TSpirvExecutionMode* spirvExecutionMode;
@ -1230,12 +1258,14 @@ protected:
std::map<TString, AstRefType> bindlessImageModeCaller;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;
bool quadDerivMode;
bool reqFullQuadsMode;
TNumericFeatures numericFeatures;
std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
std::unordered_set<int> usedConstantId; // specialization constant ids used
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
std::vector<TIoRange> usedIo[5]; // sets of used locations, one for each of in, out, uniform, and buffers
std::vector<TRange> usedIoRT[4]; // sets of used location, one for rayPayload/rayPayloadIN,
// one for callableData/callableDataIn, one for hitObjectAttributeNV and
// one for shaderrecordhitobjectNV

View File

@ -83,6 +83,11 @@ public:
const char* featureDesc);
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc);
template<typename Container>
constexpr void ppRequireExtensions(const TSourceLoc& loc, Container extensions, const char* featureDesc) {
ppRequireExtensions(loc, static_cast<int>(extensions.size()), extensions.data(), featureDesc);
}
virtual TExtensionBehavior getExtensionBehavior(const char*);
virtual bool extensionTurnedOn(const char* const extension);
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);

View File

@ -374,7 +374,7 @@ namespace {
int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; }
int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; }
int op_pos(int a) { return a; }
int op_neg(int a) { return -a; }
int op_neg(int a) { return a == INT_MIN ? INT_MIN : -a; }
int op_cmpl(int a) { return ~a; }
int op_not(int a) { return !a; }
@ -973,7 +973,8 @@ int TPpContext::readCPPline(TPpToken* ppToken)
break;
case PpAtomInclude:
if(!parseContext.isReadingHLSL()) {
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
const std::array exts = { E_GL_GOOGLE_include_directive, E_GL_ARB_shading_language_include };
parseContext.ppRequireExtensions(ppToken->loc, exts, "#include");
}
token = CPPinclude(ppToken);
break;

View File

@ -86,11 +86,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../ParseHelper.h"
#include "PpTokens.h"
/* windows only pragma */
#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif
namespace glslang {
class TPpToken {
@ -220,6 +215,7 @@ public:
virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
virtual bool isMacroInput() { return false; }
virtual bool isStringInput() { return false; }
// Will be called when we start reading tokens from this instance
virtual void notifyActivated() {}
@ -360,7 +356,8 @@ protected:
// Scanner data:
int previous_token;
TParseContextBase& parseContext;
std::vector<int> lastLineTokens;
std::vector<TSourceLoc> lastLineTokenLocs;
// Get the next token from *stack* of input sources, popping input sources
// that are out of tokens, down until an input source is found that has a token.
// Return EndOfInput when there are no more tokens to be found by doing this.
@ -374,7 +371,31 @@ protected:
break;
popInput();
}
if (!inputStack.empty() && inputStack.back()->isStringInput()) {
if (token == '\n') {
bool seenNumSign = false;
for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
int curPos = i;
int curToken = lastLineTokens[i++];
if (curToken == '#' && lastLineTokens[i] == '#') {
curToken = PpAtomPaste;
i++;
}
if (curToken == '#') {
if (seenNumSign) {
parseContext.ppError(lastLineTokenLocs[curPos], "(#) can be preceded in its line only by spaces or horizontal tabs", "#", "");
} else {
seenNumSign = true;
}
}
}
lastLineTokens.clear();
lastLineTokenLocs.clear();
} else {
lastLineTokens.push_back(token);
lastLineTokenLocs.push_back(ppToken->loc);
}
}
return token;
}
int getChar() { return inputStack.back()->getch(); }
@ -527,7 +548,7 @@ protected:
public:
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
virtual int scan(TPpToken*) override;
bool isStringInput() override { return true; }
// Scanner used to get source stream characters.
// - Escaped newlines are handled here, invisibly to the caller.
// - All forms of newline are handled, and turned into just a '\n'.

View File

@ -220,7 +220,9 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
}
if (ch >= '0' && ch <= '9') {
while (ch >= '0' && ch <= '9') {
exponent = exponent * 10 + (ch - '0');
if (exponent < 500) {
exponent = exponent * 10 + (ch - '0');
}
saveName(ch);
ch = getChar();
}

View File

@ -704,69 +704,73 @@ public:
case EbtFloat:
switch ((int)sampler.dim) {
case Esd1D:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D;
case true: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW;
}
if (sampler.shadow)
return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW;
else
return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D;
case true: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW;
}
case true: return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE;
if (sampler.ms) {
return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE;
} else {
if (sampler.shadow)
return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW;
else
return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D;
}
case Esd3D:
return GL_SAMPLER_3D;
case EsdCube:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE;
case true: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW;
}
if (sampler.shadow)
return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW;
else
return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE;
case EsdRect:
return sampler.shadow ? GL_SAMPLER_2D_RECT_SHADOW : GL_SAMPLER_2D_RECT;
case EsdBuffer:
return GL_SAMPLER_BUFFER;
default:
return 0;
}
case EbtFloat16:
switch ((int)sampler.dim) {
case Esd1D:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD;
}
if (sampler.shadow)
return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD;
else
return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD;
case Esd2D:
switch ((int)sampler.ms) {
case false:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD;
}
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD;
if (sampler.ms) {
return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD;
} else {
if (sampler.shadow)
return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD;
else
return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD;
}
case Esd3D:
return GL_FLOAT16_SAMPLER_3D_AMD;
case EsdCube:
switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD;
}
if (sampler.shadow)
return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD;
else
return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD;
case EsdRect:
return sampler.shadow ? GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_RECT_AMD;
case EsdBuffer:
return GL_FLOAT16_SAMPLER_BUFFER_AMD;
default:
return 0;
}
case EbtInt:
switch ((int)sampler.dim) {
case Esd1D:
return sampler.arrayed ? GL_INT_SAMPLER_1D_ARRAY : GL_INT_SAMPLER_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D;
case true: return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_INT_SAMPLER_2D_MULTISAMPLE;
}
if (sampler.ms)
return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_INT_SAMPLER_2D_MULTISAMPLE;
else
return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D;
case Esd3D:
return GL_INT_SAMPLER_3D;
case EsdCube:
@ -775,17 +779,19 @@ public:
return GL_INT_SAMPLER_2D_RECT;
case EsdBuffer:
return GL_INT_SAMPLER_BUFFER;
default:
return 0;
}
case EbtUint:
switch ((int)sampler.dim) {
case Esd1D:
return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : GL_UNSIGNED_INT_SAMPLER_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D;
case true: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
}
if (sampler.ms)
return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
else
return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D;
case Esd3D:
return GL_UNSIGNED_INT_SAMPLER_3D;
case EsdCube:
@ -794,6 +800,8 @@ public:
return GL_UNSIGNED_INT_SAMPLER_2D_RECT;
case EsdBuffer:
return GL_UNSIGNED_INT_SAMPLER_BUFFER;
default:
return 0;
}
default:
return 0;
@ -806,10 +814,10 @@ public:
case Esd1D:
return sampler.arrayed ? GL_IMAGE_1D_ARRAY : GL_IMAGE_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D;
case true: return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE;
}
if (sampler.ms)
return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE;
else
return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D;
case Esd3D:
return GL_IMAGE_3D;
case EsdCube:
@ -818,16 +826,18 @@ public:
return GL_IMAGE_2D_RECT;
case EsdBuffer:
return GL_IMAGE_BUFFER;
default:
return 0;
}
case EbtFloat16:
switch ((int)sampler.dim) {
case Esd1D:
return sampler.arrayed ? GL_FLOAT16_IMAGE_1D_ARRAY_AMD : GL_FLOAT16_IMAGE_1D_AMD;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD;
}
if (sampler.ms)
return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD;
else
return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD;
case Esd3D:
return GL_FLOAT16_IMAGE_3D_AMD;
case EsdCube:
@ -836,16 +846,18 @@ public:
return GL_FLOAT16_IMAGE_2D_RECT_AMD;
case EsdBuffer:
return GL_FLOAT16_IMAGE_BUFFER_AMD;
default:
return 0;
}
case EbtInt:
switch ((int)sampler.dim) {
case Esd1D:
return sampler.arrayed ? GL_INT_IMAGE_1D_ARRAY : GL_INT_IMAGE_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D;
case true: return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE;
}
if (sampler.ms)
return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE;
else
return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D;
case Esd3D:
return GL_INT_IMAGE_3D;
case EsdCube:
@ -854,17 +866,19 @@ public:
return GL_INT_IMAGE_2D_RECT;
case EsdBuffer:
return GL_INT_IMAGE_BUFFER;
default:
return 0;
}
case EbtUint:
switch ((int)sampler.dim) {
case Esd1D:
return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_1D_ARRAY : GL_UNSIGNED_INT_IMAGE_1D;
case Esd2D:
switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D;
case true: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
}
if (sampler.ms)
return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
else
return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D;
case Esd3D:
return GL_UNSIGNED_INT_IMAGE_3D;
case EsdCube:
@ -873,6 +887,8 @@ public:
return GL_UNSIGNED_INT_IMAGE_2D_RECT;
case EsdBuffer:
return GL_UNSIGNED_INT_IMAGE_BUFFER;
default:
return 0;
}
default:
return 0;
@ -937,6 +953,7 @@ public:
case 4: return GL_FLOAT_MAT4;
default: return 0;
}
default: return 0;
}
case EbtDouble:
switch (type.getMatrixCols()) {
@ -961,6 +978,7 @@ public:
case 4: return GL_DOUBLE_MAT4;
default: return 0;
}
default: return 0;
}
case EbtFloat16:
switch (type.getMatrixCols()) {
@ -985,6 +1003,7 @@ public:
case 4: return GL_FLOAT16_MAT4_AMD;
default: return 0;
}
default: return 0;
}
default:
return 0;

View File

@ -0,0 +1,94 @@
#pragma once
//
// Copyright (C) 2023 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#include <array>
// Partial implementation of std::span for C++11
// Replace with std::span if repo standard is bumped to C++20
//
// This code was copied from https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/layers/containers/custom_containers.h
template <typename T>
class span {
public:
using pointer = T *;
using const_pointer = T const *;
using iterator = pointer;
using const_iterator = const_pointer;
span() = default;
span(pointer start, size_t n) : data_(start), count_(n) {}
template <typename Iterator>
span(Iterator start, Iterator end) : data_(&(*start)), count_(end - start) {}
template <typename Container>
span(Container &c) : data_(c.data()), count_(c.size()) {}
iterator begin() { return data_; }
const_iterator begin() const { return data_; }
iterator end() { return data_ + count_; }
const_iterator end() const { return data_ + count_; }
T &operator[](int i) { return data_[i]; }
const T &operator[](int i) const { return data_[i]; }
T &front() { return *data_; }
const T &front() const { return *data_; }
T &back() { return *(data_ + (count_ - 1)); }
const T &back() const { return *(data_ + (count_ - 1)); }
size_t size() const { return count_; }
bool empty() const { return count_ == 0; }
pointer data() { return data_; }
const_pointer data() const { return data_; }
private:
pointer data_ = {};
size_t count_ = 0;
};
//
// Allow type inference that using the constructor doesn't allow in C++11
template <typename T>
span<T> make_span(T *begin, size_t count) {
return span<T>(begin, count);
}
template <typename T>
span<T> make_span(T *begin, T *end) {
return make_span<T>(begin, end);
}

View File

@ -38,6 +38,7 @@
#define _COMPILER_INTERFACE_INCLUDED_
#include "../Include/ResourceLimits.h"
#include "../Include/visibility.h"
#include "../MachineIndependent/Versions.h"
#include <cstring>
@ -49,22 +50,6 @@
#define C_DECL
#endif
#ifdef GLSLANG_IS_SHARED_LIBRARY
#ifdef _WIN32
#ifdef GLSLANG_EXPORTING
#define GLSLANG_EXPORT __declspec(dllexport)
#else
#define GLSLANG_EXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define GLSLANG_EXPORT __attribute__((visibility("default")))
#endif
#endif // GLSLANG_IS_SHARED_LIBRARY
#ifndef GLSLANG_EXPORT
#define GLSLANG_EXPORT
#endif
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler/linker.
@ -252,23 +237,25 @@ typedef enum {
// Message choices for what errors and warnings are given.
//
enum EShMessages : unsigned {
EShMsgDefault = 0, // default is to give all required errors and extra warnings
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
EShMsgAST = (1 << 2), // print the AST intermediate representation
EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
EShMsgDebugInfo = (1 << 10), // save debug information
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
EShMsgEnhanced = (1 << 15), // enhanced message readability
EShMsgDefault = 0, // default is to give all required errors and extra warnings
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
EShMsgAST = (1 << 2), // print the AST intermediate representation
EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
EShMsgDebugInfo = (1 << 10), // save debug information
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
EShMsgEnhanced = (1 << 15), // enhanced message readability
EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages
EShMsgDisplayErrorColumn = (1 << 17), // Display error message column aswell as line
LAST_ELEMENT_MARKER(EShMsgCount),
};
@ -335,7 +322,8 @@ GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[],
int, // debugOptions unused
int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
bool forwardCompatible = false, // give errors for use of deprecated features
EShMessages messages = EShMsgDefault // warnings and errors
EShMessages messages = EShMsgDefault, // warnings and errors
const char* fileName = nullptr
);
GLSLANG_EXPORT int ShLinkExt(
@ -507,6 +495,9 @@ public:
GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set);
GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding);
GLSLANG_EXPORT void addSourceText(const char* text, size_t len);
GLSLANG_EXPORT void setSourceFile(const char* file);
// For setting up the environment (cleared to nothingness in the constructor).
// These must be called so that parsing is done for the right source language and
// target environment, either indirectly through TranslateEnvironment() based on
@ -743,6 +734,8 @@ public:
GLSLANG_EXPORT void dump() const;
static TObjectReflection badReflection() { return TObjectReflection(); }
GLSLANG_EXPORT unsigned int layoutLocation() const;
std::string name;
int offset;
int glDefineType;

View File

@ -42,28 +42,14 @@ const glslang_resource_t* glslang_default_resource(void)
return reinterpret_cast<const glslang_resource_t*>(GetDefaultResources());
}
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
const char* glslang_default_resource_string()
{
std::string cpp_str = GetDefaultTBuiltInResourceString();
char* c_str = (char*)malloc(cpp_str.length() + 1);
strcpy(c_str, cpp_str.c_str());
strncpy(c_str, cpp_str.c_str(), cpp_str.length() + 1);
return c_str;
}
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
void glslang_decode_resource_limits(glslang_resource_t* resources, char* config)
{
DecodeResourceLimits(reinterpret_cast<TBuiltInResource*>(resources), config);

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2024 The Khronos Group Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -32,6 +32,6 @@
// POSSIBILITY OF SUCH DAMAGE.
//
namespace glslang {
} // end namespace glslang
// This empty source file exists to support building stubbed versions of
// deprecated libraries which have been integrated into the main glslang
// library. It should be deleted once the stub libraries are fully removed.

View File

@ -2,7 +2,7 @@
// File: vk_platform.h
//
/*
** Copyright 2014-2023 The Khronos Group Inc.
** Copyright 2014-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -0,0 +1,392 @@
#ifndef VULKAN_VIDEO_CODEC_AV1STD_H_
#define VULKAN_VIDEO_CODEC_AV1STD_H_ 1
/*
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
// vulkan_video_codec_av1std is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_av1std 1
#include "vulkan_video_codecs_common.h"
#define STD_VIDEO_AV1_NUM_REF_FRAMES 8
#define STD_VIDEO_AV1_REFS_PER_FRAME 7
#define STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME 8
#define STD_VIDEO_AV1_MAX_TILE_COLS 64
#define STD_VIDEO_AV1_MAX_TILE_ROWS 64
#define STD_VIDEO_AV1_MAX_SEGMENTS 8
#define STD_VIDEO_AV1_SEG_LVL_MAX 8
#define STD_VIDEO_AV1_PRIMARY_REF_NONE 7
#define STD_VIDEO_AV1_SELECT_INTEGER_MV 2
#define STD_VIDEO_AV1_SELECT_SCREEN_CONTENT_TOOLS 2
#define STD_VIDEO_AV1_SKIP_MODE_FRAMES 2
#define STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS 4
#define STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS 2
#define STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS 8
#define STD_VIDEO_AV1_MAX_NUM_PLANES 3
#define STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS 6
#define STD_VIDEO_AV1_MAX_NUM_Y_POINTS 14
#define STD_VIDEO_AV1_MAX_NUM_CB_POINTS 10
#define STD_VIDEO_AV1_MAX_NUM_CR_POINTS 10
#define STD_VIDEO_AV1_MAX_NUM_POS_LUMA 24
#define STD_VIDEO_AV1_MAX_NUM_POS_CHROMA 25
typedef enum StdVideoAV1Profile {
STD_VIDEO_AV1_PROFILE_MAIN = 0,
STD_VIDEO_AV1_PROFILE_HIGH = 1,
STD_VIDEO_AV1_PROFILE_PROFESSIONAL = 2,
STD_VIDEO_AV1_PROFILE_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_PROFILE_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1Profile;
typedef enum StdVideoAV1Level {
STD_VIDEO_AV1_LEVEL_2_0 = 0,
STD_VIDEO_AV1_LEVEL_2_1 = 1,
STD_VIDEO_AV1_LEVEL_2_2 = 2,
STD_VIDEO_AV1_LEVEL_2_3 = 3,
STD_VIDEO_AV1_LEVEL_3_0 = 4,
STD_VIDEO_AV1_LEVEL_3_1 = 5,
STD_VIDEO_AV1_LEVEL_3_2 = 6,
STD_VIDEO_AV1_LEVEL_3_3 = 7,
STD_VIDEO_AV1_LEVEL_4_0 = 8,
STD_VIDEO_AV1_LEVEL_4_1 = 9,
STD_VIDEO_AV1_LEVEL_4_2 = 10,
STD_VIDEO_AV1_LEVEL_4_3 = 11,
STD_VIDEO_AV1_LEVEL_5_0 = 12,
STD_VIDEO_AV1_LEVEL_5_1 = 13,
STD_VIDEO_AV1_LEVEL_5_2 = 14,
STD_VIDEO_AV1_LEVEL_5_3 = 15,
STD_VIDEO_AV1_LEVEL_6_0 = 16,
STD_VIDEO_AV1_LEVEL_6_1 = 17,
STD_VIDEO_AV1_LEVEL_6_2 = 18,
STD_VIDEO_AV1_LEVEL_6_3 = 19,
STD_VIDEO_AV1_LEVEL_7_0 = 20,
STD_VIDEO_AV1_LEVEL_7_1 = 21,
STD_VIDEO_AV1_LEVEL_7_2 = 22,
STD_VIDEO_AV1_LEVEL_7_3 = 23,
STD_VIDEO_AV1_LEVEL_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_LEVEL_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1Level;
typedef enum StdVideoAV1FrameType {
STD_VIDEO_AV1_FRAME_TYPE_KEY = 0,
STD_VIDEO_AV1_FRAME_TYPE_INTER = 1,
STD_VIDEO_AV1_FRAME_TYPE_INTRA_ONLY = 2,
STD_VIDEO_AV1_FRAME_TYPE_SWITCH = 3,
STD_VIDEO_AV1_FRAME_TYPE_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_FRAME_TYPE_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1FrameType;
typedef enum StdVideoAV1ReferenceName {
STD_VIDEO_AV1_REFERENCE_NAME_INTRA_FRAME = 0,
STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME = 1,
STD_VIDEO_AV1_REFERENCE_NAME_LAST2_FRAME = 2,
STD_VIDEO_AV1_REFERENCE_NAME_LAST3_FRAME = 3,
STD_VIDEO_AV1_REFERENCE_NAME_GOLDEN_FRAME = 4,
STD_VIDEO_AV1_REFERENCE_NAME_BWDREF_FRAME = 5,
STD_VIDEO_AV1_REFERENCE_NAME_ALTREF2_FRAME = 6,
STD_VIDEO_AV1_REFERENCE_NAME_ALTREF_FRAME = 7,
STD_VIDEO_AV1_REFERENCE_NAME_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_REFERENCE_NAME_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1ReferenceName;
typedef enum StdVideoAV1InterpolationFilter {
STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP = 0,
STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH = 1,
STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP = 2,
STD_VIDEO_AV1_INTERPOLATION_FILTER_BILINEAR = 3,
STD_VIDEO_AV1_INTERPOLATION_FILTER_SWITCHABLE = 4,
STD_VIDEO_AV1_INTERPOLATION_FILTER_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_INTERPOLATION_FILTER_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1InterpolationFilter;
typedef enum StdVideoAV1TxMode {
STD_VIDEO_AV1_TX_MODE_ONLY_4X4 = 0,
STD_VIDEO_AV1_TX_MODE_LARGEST = 1,
STD_VIDEO_AV1_TX_MODE_SELECT = 2,
STD_VIDEO_AV1_TX_MODE_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_TX_MODE_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1TxMode;
typedef enum StdVideoAV1FrameRestorationType {
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE = 0,
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_WIENER = 1,
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SGRPROJ = 2,
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_SWITCHABLE = 3,
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1FrameRestorationType;
typedef enum StdVideoAV1ColorPrimaries {
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_709 = 1,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = 2,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_M = 4,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_B_G = 5,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_601 = 6,
STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_240 = 7,
STD_VIDEO_AV1_COLOR_PRIMARIES_GENERIC_FILM = 8,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_2020 = 9,
STD_VIDEO_AV1_COLOR_PRIMARIES_XYZ = 10,
STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_431 = 11,
STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_432 = 12,
STD_VIDEO_AV1_COLOR_PRIMARIES_EBU_3213 = 22,
STD_VIDEO_AV1_COLOR_PRIMARIES_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_COLOR_PRIMARIES_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1ColorPrimaries;
typedef enum StdVideoAV1TransferCharacteristics {
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_0 = 0,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_709 = 1,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_UNSPECIFIED = 2,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_RESERVED_3 = 3,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_M = 4,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_470_B_G = 5,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_601 = 6,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_240 = 7,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LINEAR = 8,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100 = 9,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_LOG_100_SQRT10 = 10,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_IEC_61966 = 11,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_1361 = 12,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SRGB = 13,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_10_BIT = 14,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_BT_2020_12_BIT = 15,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_2084 = 16,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_SMPTE_428 = 17,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_HLG = 18,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1TransferCharacteristics;
typedef enum StdVideoAV1MatrixCoefficients {
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_IDENTITY = 0,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_709 = 1,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_UNSPECIFIED = 2,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_RESERVED_3 = 3,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_FCC = 4,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_470_B_G = 5,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_601 = 6,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_240 = 7,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_YCGCO = 8,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_NCL = 9,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_BT_2020_CL = 10,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_SMPTE_2085 = 11,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_NCL = 12,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_CHROMAT_CL = 13,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_ICTCP = 14,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_MATRIX_COEFFICIENTS_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1MatrixCoefficients;
typedef enum StdVideoAV1ChromaSamplePosition {
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_UNKNOWN = 0,
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_VERTICAL = 1,
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_COLOCATED = 2,
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_RESERVED = 3,
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_INVALID = 0x7FFFFFFF,
STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1ChromaSamplePosition;
typedef struct StdVideoAV1ColorConfigFlags {
uint32_t mono_chrome : 1;
uint32_t color_range : 1;
uint32_t separate_uv_delta_q : 1;
uint32_t color_description_present_flag : 1;
uint32_t reserved : 28;
} StdVideoAV1ColorConfigFlags;
typedef struct StdVideoAV1ColorConfig {
StdVideoAV1ColorConfigFlags flags;
uint8_t BitDepth;
uint8_t subsampling_x;
uint8_t subsampling_y;
uint8_t reserved1;
StdVideoAV1ColorPrimaries color_primaries;
StdVideoAV1TransferCharacteristics transfer_characteristics;
StdVideoAV1MatrixCoefficients matrix_coefficients;
StdVideoAV1ChromaSamplePosition chroma_sample_position;
} StdVideoAV1ColorConfig;
typedef struct StdVideoAV1TimingInfoFlags {
uint32_t equal_picture_interval : 1;
uint32_t reserved : 31;
} StdVideoAV1TimingInfoFlags;
typedef struct StdVideoAV1TimingInfo {
StdVideoAV1TimingInfoFlags flags;
uint32_t num_units_in_display_tick;
uint32_t time_scale;
uint32_t num_ticks_per_picture_minus_1;
} StdVideoAV1TimingInfo;
typedef struct StdVideoAV1LoopFilterFlags {
uint32_t loop_filter_delta_enabled : 1;
uint32_t loop_filter_delta_update : 1;
uint32_t reserved : 30;
} StdVideoAV1LoopFilterFlags;
typedef struct StdVideoAV1LoopFilter {
StdVideoAV1LoopFilterFlags flags;
uint8_t loop_filter_level[STD_VIDEO_AV1_MAX_LOOP_FILTER_STRENGTHS];
uint8_t loop_filter_sharpness;
uint8_t update_ref_delta;
int8_t loop_filter_ref_deltas[STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME];
uint8_t update_mode_delta;
int8_t loop_filter_mode_deltas[STD_VIDEO_AV1_LOOP_FILTER_ADJUSTMENTS];
} StdVideoAV1LoopFilter;
typedef struct StdVideoAV1QuantizationFlags {
uint32_t using_qmatrix : 1;
uint32_t diff_uv_delta : 1;
uint32_t reserved : 30;
} StdVideoAV1QuantizationFlags;
typedef struct StdVideoAV1Quantization {
StdVideoAV1QuantizationFlags flags;
uint8_t base_q_idx;
int8_t DeltaQYDc;
int8_t DeltaQUDc;
int8_t DeltaQUAc;
int8_t DeltaQVDc;
int8_t DeltaQVAc;
uint8_t qm_y;
uint8_t qm_u;
uint8_t qm_v;
} StdVideoAV1Quantization;
typedef struct StdVideoAV1Segmentation {
uint8_t FeatureEnabled[STD_VIDEO_AV1_MAX_SEGMENTS];
int16_t FeatureData[STD_VIDEO_AV1_MAX_SEGMENTS][STD_VIDEO_AV1_SEG_LVL_MAX];
} StdVideoAV1Segmentation;
typedef struct StdVideoAV1TileInfoFlags {
uint32_t uniform_tile_spacing_flag : 1;
uint32_t reserved : 31;
} StdVideoAV1TileInfoFlags;
typedef struct StdVideoAV1TileInfo {
StdVideoAV1TileInfoFlags flags;
uint8_t TileCols;
uint8_t TileRows;
uint16_t context_update_tile_id;
uint8_t tile_size_bytes_minus_1;
uint8_t reserved1[7];
const uint16_t* pMiColStarts;
const uint16_t* pMiRowStarts;
const uint16_t* pWidthInSbsMinus1;
const uint16_t* pHeightInSbsMinus1;
} StdVideoAV1TileInfo;
typedef struct StdVideoAV1CDEF {
uint8_t cdef_damping_minus_3;
uint8_t cdef_bits;
uint8_t cdef_y_pri_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS];
uint8_t cdef_y_sec_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS];
uint8_t cdef_uv_pri_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS];
uint8_t cdef_uv_sec_strength[STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS];
} StdVideoAV1CDEF;
typedef struct StdVideoAV1LoopRestoration {
StdVideoAV1FrameRestorationType FrameRestorationType[STD_VIDEO_AV1_MAX_NUM_PLANES];
uint16_t LoopRestorationSize[STD_VIDEO_AV1_MAX_NUM_PLANES];
} StdVideoAV1LoopRestoration;
typedef struct StdVideoAV1GlobalMotion {
uint8_t GmType[STD_VIDEO_AV1_NUM_REF_FRAMES];
int32_t gm_params[STD_VIDEO_AV1_NUM_REF_FRAMES][STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS];
} StdVideoAV1GlobalMotion;
typedef struct StdVideoAV1FilmGrainFlags {
uint32_t chroma_scaling_from_luma : 1;
uint32_t overlap_flag : 1;
uint32_t clip_to_restricted_range : 1;
uint32_t update_grain : 1;
uint32_t reserved : 28;
} StdVideoAV1FilmGrainFlags;
typedef struct StdVideoAV1FilmGrain {
StdVideoAV1FilmGrainFlags flags;
uint8_t grain_scaling_minus_8;
uint8_t ar_coeff_lag;
uint8_t ar_coeff_shift_minus_6;
uint8_t grain_scale_shift;
uint16_t grain_seed;
uint8_t film_grain_params_ref_idx;
uint8_t num_y_points;
uint8_t point_y_value[STD_VIDEO_AV1_MAX_NUM_Y_POINTS];
uint8_t point_y_scaling[STD_VIDEO_AV1_MAX_NUM_Y_POINTS];
uint8_t num_cb_points;
uint8_t point_cb_value[STD_VIDEO_AV1_MAX_NUM_CB_POINTS];
uint8_t point_cb_scaling[STD_VIDEO_AV1_MAX_NUM_CB_POINTS];
uint8_t num_cr_points;
uint8_t point_cr_value[STD_VIDEO_AV1_MAX_NUM_CR_POINTS];
uint8_t point_cr_scaling[STD_VIDEO_AV1_MAX_NUM_CR_POINTS];
int8_t ar_coeffs_y_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_LUMA];
int8_t ar_coeffs_cb_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_CHROMA];
int8_t ar_coeffs_cr_plus_128[STD_VIDEO_AV1_MAX_NUM_POS_CHROMA];
uint8_t cb_mult;
uint8_t cb_luma_mult;
uint16_t cb_offset;
uint8_t cr_mult;
uint8_t cr_luma_mult;
uint16_t cr_offset;
} StdVideoAV1FilmGrain;
typedef struct StdVideoAV1SequenceHeaderFlags {
uint32_t still_picture : 1;
uint32_t reduced_still_picture_header : 1;
uint32_t use_128x128_superblock : 1;
uint32_t enable_filter_intra : 1;
uint32_t enable_intra_edge_filter : 1;
uint32_t enable_interintra_compound : 1;
uint32_t enable_masked_compound : 1;
uint32_t enable_warped_motion : 1;
uint32_t enable_dual_filter : 1;
uint32_t enable_order_hint : 1;
uint32_t enable_jnt_comp : 1;
uint32_t enable_ref_frame_mvs : 1;
uint32_t frame_id_numbers_present_flag : 1;
uint32_t enable_superres : 1;
uint32_t enable_cdef : 1;
uint32_t enable_restoration : 1;
uint32_t film_grain_params_present : 1;
uint32_t timing_info_present_flag : 1;
uint32_t initial_display_delay_present_flag : 1;
uint32_t reserved : 13;
} StdVideoAV1SequenceHeaderFlags;
typedef struct StdVideoAV1SequenceHeader {
StdVideoAV1SequenceHeaderFlags flags;
StdVideoAV1Profile seq_profile;
uint8_t frame_width_bits_minus_1;
uint8_t frame_height_bits_minus_1;
uint16_t max_frame_width_minus_1;
uint16_t max_frame_height_minus_1;
uint8_t delta_frame_id_length_minus_2;
uint8_t additional_frame_id_length_minus_1;
uint8_t order_hint_bits_minus_1;
uint8_t seq_force_integer_mv;
uint8_t seq_force_screen_content_tools;
uint8_t reserved1[5];
const StdVideoAV1ColorConfig* pColorConfig;
const StdVideoAV1TimingInfo* pTimingInfo;
} StdVideoAV1SequenceHeader;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,109 @@
#ifndef VULKAN_VIDEO_CODEC_AV1STD_DECODE_H_
#define VULKAN_VIDEO_CODEC_AV1STD_DECODE_H_ 1
/*
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
// vulkan_video_codec_av1std_decode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_av1std_decode 1
#include "vulkan_video_codec_av1std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_decode"
typedef struct StdVideoDecodeAV1PictureInfoFlags {
uint32_t error_resilient_mode : 1;
uint32_t disable_cdf_update : 1;
uint32_t use_superres : 1;
uint32_t render_and_frame_size_different : 1;
uint32_t allow_screen_content_tools : 1;
uint32_t is_filter_switchable : 1;
uint32_t force_integer_mv : 1;
uint32_t frame_size_override_flag : 1;
uint32_t buffer_removal_time_present_flag : 1;
uint32_t allow_intrabc : 1;
uint32_t frame_refs_short_signaling : 1;
uint32_t allow_high_precision_mv : 1;
uint32_t is_motion_mode_switchable : 1;
uint32_t use_ref_frame_mvs : 1;
uint32_t disable_frame_end_update_cdf : 1;
uint32_t allow_warped_motion : 1;
uint32_t reduced_tx_set : 1;
uint32_t reference_select : 1;
uint32_t skip_mode_present : 1;
uint32_t delta_q_present : 1;
uint32_t delta_lf_present : 1;
uint32_t delta_lf_multi : 1;
uint32_t segmentation_enabled : 1;
uint32_t segmentation_update_map : 1;
uint32_t segmentation_temporal_update : 1;
uint32_t segmentation_update_data : 1;
uint32_t UsesLr : 1;
uint32_t usesChromaLr : 1;
uint32_t apply_grain : 1;
uint32_t reserved : 3;
} StdVideoDecodeAV1PictureInfoFlags;
typedef struct StdVideoDecodeAV1PictureInfo {
StdVideoDecodeAV1PictureInfoFlags flags;
StdVideoAV1FrameType frame_type;
uint32_t current_frame_id;
uint8_t OrderHint;
uint8_t primary_ref_frame;
uint8_t refresh_frame_flags;
uint8_t reserved1;
StdVideoAV1InterpolationFilter interpolation_filter;
StdVideoAV1TxMode TxMode;
uint8_t delta_q_res;
uint8_t delta_lf_res;
uint8_t SkipModeFrame[STD_VIDEO_AV1_SKIP_MODE_FRAMES];
uint8_t coded_denom;
uint8_t reserved2[3];
uint8_t OrderHints[STD_VIDEO_AV1_NUM_REF_FRAMES];
uint32_t expectedFrameId[STD_VIDEO_AV1_NUM_REF_FRAMES];
const StdVideoAV1TileInfo* pTileInfo;
const StdVideoAV1Quantization* pQuantization;
const StdVideoAV1Segmentation* pSegmentation;
const StdVideoAV1LoopFilter* pLoopFilter;
const StdVideoAV1CDEF* pCDEF;
const StdVideoAV1LoopRestoration* pLoopRestoration;
const StdVideoAV1GlobalMotion* pGlobalMotion;
const StdVideoAV1FilmGrain* pFilmGrain;
} StdVideoDecodeAV1PictureInfo;
typedef struct StdVideoDecodeAV1ReferenceInfoFlags {
uint32_t disable_frame_end_update_cdf : 1;
uint32_t segmentation_enabled : 1;
uint32_t reserved : 30;
} StdVideoDecodeAV1ReferenceInfoFlags;
typedef struct StdVideoDecodeAV1ReferenceInfo {
StdVideoDecodeAV1ReferenceInfoFlags flags;
uint8_t frame_type;
uint8_t RefFrameSignBias;
uint8_t OrderHint;
uint8_t SavedOrderHints[STD_VIDEO_AV1_NUM_REF_FRAMES];
} StdVideoDecodeAV1ReferenceInfo;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,8 +19,9 @@ extern "C" {
// vulkan_video_codec_h264std is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h264std 1
#include <stdint.h>
#include "vulkan_video_codecs_common.h"
#define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32
#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6
#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16
@ -28,6 +29,7 @@ extern "C" {
#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64
#define STD_VIDEO_H264_MAX_NUM_LIST_REF 32
#define STD_VIDEO_H264_MAX_CHROMA_PLANES 2
#define STD_VIDEO_H264_NO_REFERENCE_PICTURE 0xFF
typedef enum StdVideoH264ChromaFormatIdc {
STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME = 0,

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,13 +19,15 @@ extern "C" {
// vulkan_video_codec_h264std_decode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h264std_decode 1
#include "vulkan_video_codec_h264std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode"
#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2
typedef enum StdVideoDecodeH264FieldOrderCount {
STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0,

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,11 +19,13 @@ extern "C" {
// vulkan_video_codec_h264std_encode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h264std_encode 1
// Vulkan 0.9 provisional Vulkan video H.264 encode std specification version number
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8 VK_MAKE_VIDEO_STD_VERSION(0, 9, 8)
#include "vulkan_video_codec_h264std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode"
typedef struct StdVideoEncodeH264WeightTableFlags {
uint32_t luma_weight_l0_flag;
@ -49,25 +51,28 @@ typedef struct StdVideoEncodeH264WeightTable {
typedef struct StdVideoEncodeH264SliceHeaderFlags {
uint32_t direct_spatial_mv_pred_flag : 1;
uint32_t num_ref_idx_active_override_flag : 1;
uint32_t no_output_of_prior_pics_flag : 1;
uint32_t adaptive_ref_pic_marking_mode_flag : 1;
uint32_t no_prior_references_available_flag : 1;
uint32_t reserved : 30;
} StdVideoEncodeH264SliceHeaderFlags;
typedef struct StdVideoEncodeH264PictureInfoFlags {
uint32_t idr_flag : 1;
uint32_t is_reference_flag : 1;
uint32_t used_for_long_term_reference : 1;
uint32_t IdrPicFlag : 1;
uint32_t is_reference : 1;
uint32_t no_output_of_prior_pics_flag : 1;
uint32_t long_term_reference_flag : 1;
uint32_t adaptive_ref_pic_marking_mode_flag : 1;
uint32_t reserved : 27;
} StdVideoEncodeH264PictureInfoFlags;
typedef struct StdVideoEncodeH264ReferenceInfoFlags {
uint32_t used_for_long_term_reference : 1;
uint32_t reserved : 31;
} StdVideoEncodeH264ReferenceInfoFlags;
typedef struct StdVideoEncodeH264RefMgmtFlags {
uint32_t ref_pic_list_modification_l0_flag : 1;
uint32_t ref_pic_list_modification_l1_flag : 1;
} StdVideoEncodeH264RefMgmtFlags;
typedef struct StdVideoEncodeH264ReferenceListsInfoFlags {
uint32_t ref_pic_list_modification_flag_l0 : 1;
uint32_t ref_pic_list_modification_flag_l1 : 1;
uint32_t reserved : 30;
} StdVideoEncodeH264ReferenceListsInfoFlags;
typedef struct StdVideoEncodeH264RefListModEntry {
StdVideoH264ModificationOfPicNumsIdc modification_of_pic_nums_idc;
@ -76,51 +81,61 @@ typedef struct StdVideoEncodeH264RefListModEntry {
} StdVideoEncodeH264RefListModEntry;
typedef struct StdVideoEncodeH264RefPicMarkingEntry {
StdVideoH264MemMgmtControlOp operation;
StdVideoH264MemMgmtControlOp memory_management_control_operation;
uint16_t difference_of_pic_nums_minus1;
uint16_t long_term_pic_num;
uint16_t long_term_frame_idx;
uint16_t max_long_term_frame_idx_plus1;
} StdVideoEncodeH264RefPicMarkingEntry;
typedef struct StdVideoEncodeH264RefMemMgmtCtrlOperations {
StdVideoEncodeH264RefMgmtFlags flags;
typedef struct StdVideoEncodeH264ReferenceListsInfo {
StdVideoEncodeH264ReferenceListsInfoFlags flags;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint8_t RefPicList0[STD_VIDEO_H264_MAX_NUM_LIST_REF];
uint8_t RefPicList1[STD_VIDEO_H264_MAX_NUM_LIST_REF];
uint8_t refList0ModOpCount;
const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
uint8_t refList1ModOpCount;
const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
uint8_t refPicMarkingOpCount;
uint8_t reserved1[7];
const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations;
} StdVideoEncodeH264RefMemMgmtCtrlOperations;
} StdVideoEncodeH264ReferenceListsInfo;
typedef struct StdVideoEncodeH264PictureInfo {
StdVideoEncodeH264PictureInfoFlags flags;
uint8_t seq_parameter_set_id;
uint8_t pic_parameter_set_id;
StdVideoH264PictureType pictureType;
uint32_t frame_num;
int32_t PicOrderCnt;
StdVideoEncodeH264PictureInfoFlags flags;
uint8_t seq_parameter_set_id;
uint8_t pic_parameter_set_id;
uint16_t idr_pic_id;
StdVideoH264PictureType primary_pic_type;
uint32_t frame_num;
int32_t PicOrderCnt;
uint8_t temporal_id;
uint8_t reserved1[3];
const StdVideoEncodeH264ReferenceListsInfo* pRefLists;
} StdVideoEncodeH264PictureInfo;
typedef struct StdVideoEncodeH264ReferenceInfo {
StdVideoEncodeH264ReferenceInfoFlags flags;
StdVideoH264PictureType primary_pic_type;
uint32_t FrameNum;
int32_t PicOrderCnt;
uint16_t long_term_pic_num;
uint16_t long_term_frame_idx;
uint8_t temporal_id;
} StdVideoEncodeH264ReferenceInfo;
typedef struct StdVideoEncodeH264SliceHeader {
StdVideoEncodeH264SliceHeaderFlags flags;
uint32_t first_mb_in_slice;
StdVideoH264SliceType slice_type;
uint16_t idr_pic_id;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
StdVideoH264CabacInitIdc cabac_init_idc;
StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc;
int8_t slice_alpha_c0_offset_div2;
int8_t slice_beta_offset_div2;
int8_t slice_qp_delta;
uint8_t reserved1;
StdVideoH264CabacInitIdc cabac_init_idc;
StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc;
const StdVideoEncodeH264WeightTable* pWeightTable;
} StdVideoEncodeH264SliceHeader;

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,9 +19,11 @@ extern "C" {
// vulkan_video_codec_h265std is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h265std 1
#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7
#include "vulkan_video_codecs_common.h"
#define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32
#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7
#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6
#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16
#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6
@ -30,18 +32,19 @@ extern "C" {
#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64
#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2
#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128
#define STD_VIDEO_H265_MAX_DPB_SIZE 16
#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128
#define STD_VIDEO_H265_MAX_NUM_LIST_REF 15
#define STD_VIDEO_H265_MAX_CHROMA_PLANES 2
#define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64
#define STD_VIDEO_H265_MAX_DPB_SIZE 16
#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32
#define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16
#define STD_VIDEO_H265_MAX_DELTA_POC 48
#define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFF
typedef enum StdVideoH265ChromaFormatIdc {
STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0,

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,13 +19,15 @@ extern "C" {
// vulkan_video_codec_h265std_decode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h265std_decode 1
#include "vulkan_video_codec_h265std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode"
#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8
typedef struct StdVideoDecodeH265PictureInfoFlags {
uint32_t IrapPicFlag : 1;
uint32_t IdrPicFlag : 1;

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,11 +19,13 @@ extern "C" {
// vulkan_video_codec_h265std_encode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_h265std_encode 1
// Vulkan 0.9 provisional Vulkan video H.265 encode std specification version number
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9)
#include "vulkan_video_codec_h265std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode"
typedef struct StdVideoEncodeH265WeightTableFlags {
uint16_t luma_weight_l0_flag;
@ -48,11 +50,7 @@ typedef struct StdVideoEncodeH265WeightTable {
typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags {
uint32_t first_slice_segment_in_pic_flag : 1;
uint32_t no_output_of_prior_pics_flag : 1;
uint32_t dependent_slice_segment_flag : 1;
uint32_t pic_output_flag : 1;
uint32_t short_term_ref_pic_set_sps_flag : 1;
uint32_t slice_temporal_mvp_enable_flag : 1;
uint32_t slice_sao_luma_flag : 1;
uint32_t slice_sao_chroma_flag : 1;
uint32_t num_ref_idx_active_override_flag : 1;
@ -63,9 +61,57 @@ typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags {
uint32_t slice_deblocking_filter_disabled_flag : 1;
uint32_t collocated_from_l0_flag : 1;
uint32_t slice_loop_filter_across_slices_enabled_flag : 1;
uint32_t reserved : 20;
} StdVideoEncodeH265SliceSegmentHeaderFlags;
typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics {
typedef struct StdVideoEncodeH265SliceSegmentHeader {
StdVideoEncodeH265SliceSegmentHeaderFlags flags;
StdVideoH265SliceType slice_type;
uint32_t slice_segment_address;
uint8_t collocated_ref_idx;
uint8_t MaxNumMergeCand;
int8_t slice_cb_qp_offset;
int8_t slice_cr_qp_offset;
int8_t slice_beta_offset_div2;
int8_t slice_tc_offset_div2;
int8_t slice_act_y_qp_offset;
int8_t slice_act_cb_qp_offset;
int8_t slice_act_cr_qp_offset;
int8_t slice_qp_delta;
uint16_t reserved1;
const StdVideoEncodeH265WeightTable* pWeightTable;
} StdVideoEncodeH265SliceSegmentHeader;
typedef struct StdVideoEncodeH265ReferenceListsInfoFlags {
uint32_t ref_pic_list_modification_flag_l0 : 1;
uint32_t ref_pic_list_modification_flag_l1 : 1;
uint32_t reserved : 30;
} StdVideoEncodeH265ReferenceListsInfoFlags;
typedef struct StdVideoEncodeH265ReferenceListsInfo {
StdVideoEncodeH265ReferenceListsInfoFlags flags;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint8_t RefPicList0[STD_VIDEO_H265_MAX_NUM_LIST_REF];
uint8_t RefPicList1[STD_VIDEO_H265_MAX_NUM_LIST_REF];
uint8_t list_entry_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF];
uint8_t list_entry_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF];
} StdVideoEncodeH265ReferenceListsInfo;
typedef struct StdVideoEncodeH265PictureInfoFlags {
uint32_t is_reference : 1;
uint32_t IrapPicFlag : 1;
uint32_t used_for_long_term_reference : 1;
uint32_t discardable_flag : 1;
uint32_t cross_layer_bla_flag : 1;
uint32_t pic_output_flag : 1;
uint32_t no_output_of_prior_pics_flag : 1;
uint32_t short_term_ref_pic_set_sps_flag : 1;
uint32_t slice_temporal_mvp_enabled_flag : 1;
uint32_t reserved : 23;
} StdVideoEncodeH265PictureInfoFlags;
typedef struct StdVideoEncodeH265LongTermRefPics {
uint8_t num_long_term_sps;
uint8_t num_long_term_pics;
uint8_t lt_idx_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS];
@ -73,67 +119,32 @@ typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics {
uint16_t used_by_curr_pic_lt_flag;
uint8_t delta_poc_msb_present_flag[STD_VIDEO_H265_MAX_DELTA_POC];
uint8_t delta_poc_msb_cycle_lt[STD_VIDEO_H265_MAX_DELTA_POC];
} StdVideoEncodeH265SliceSegmentLongTermRefPics;
typedef struct StdVideoEncodeH265SliceSegmentHeader {
StdVideoEncodeH265SliceSegmentHeaderFlags flags;
StdVideoH265SliceType slice_type;
uint32_t slice_segment_address;
uint8_t short_term_ref_pic_set_idx;
uint8_t collocated_ref_idx;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint8_t MaxNumMergeCand;
int8_t slice_cb_qp_offset;
int8_t slice_cr_qp_offset;
int8_t slice_beta_offset_div2;
int8_t slice_tc_offset_div2;
int8_t slice_act_y_qp_offset;
int8_t slice_act_cb_qp_offset;
int8_t slice_act_cr_qp_offset;
const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet;
const StdVideoEncodeH265SliceSegmentLongTermRefPics* pLongTermRefPics;
const StdVideoEncodeH265WeightTable* pWeightTable;
} StdVideoEncodeH265SliceSegmentHeader;
typedef struct StdVideoEncodeH265ReferenceModificationFlags {
uint32_t ref_pic_list_modification_flag_l0 : 1;
uint32_t ref_pic_list_modification_flag_l1 : 1;
} StdVideoEncodeH265ReferenceModificationFlags;
typedef struct StdVideoEncodeH265ReferenceModifications {
StdVideoEncodeH265ReferenceModificationFlags flags;
uint8_t referenceList0ModificationsCount;
const uint8_t* pReferenceList0Modifications;
uint8_t referenceList1ModificationsCount;
const uint8_t* pReferenceList1Modifications;
} StdVideoEncodeH265ReferenceModifications;
typedef struct StdVideoEncodeH265PictureInfoFlags {
uint32_t is_reference_flag : 1;
uint32_t IrapPicFlag : 1;
uint32_t long_term_flag : 1;
uint32_t discardable_flag : 1;
uint32_t cross_layer_bla_flag : 1;
} StdVideoEncodeH265PictureInfoFlags;
} StdVideoEncodeH265LongTermRefPics;
typedef struct StdVideoEncodeH265PictureInfo {
StdVideoEncodeH265PictureInfoFlags flags;
StdVideoH265PictureType PictureType;
uint8_t sps_video_parameter_set_id;
uint8_t pps_seq_parameter_set_id;
uint8_t pps_pic_parameter_set_id;
int32_t PicOrderCntVal;
uint8_t TemporalId;
StdVideoEncodeH265PictureInfoFlags flags;
StdVideoH265PictureType pic_type;
uint8_t sps_video_parameter_set_id;
uint8_t pps_seq_parameter_set_id;
uint8_t pps_pic_parameter_set_id;
uint8_t short_term_ref_pic_set_idx;
int32_t PicOrderCntVal;
uint8_t TemporalId;
uint8_t reserved1[7];
const StdVideoEncodeH265ReferenceListsInfo* pRefLists;
const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet;
const StdVideoEncodeH265LongTermRefPics* pLongTermRefPics;
} StdVideoEncodeH265PictureInfo;
typedef struct StdVideoEncodeH265ReferenceInfoFlags {
uint32_t used_for_long_term_reference : 1;
uint32_t unused_for_reference : 1;
uint32_t reserved : 30;
} StdVideoEncodeH265ReferenceInfoFlags;
typedef struct StdVideoEncodeH265ReferenceInfo {
StdVideoEncodeH265ReferenceInfoFlags flags;
StdVideoH265PictureType pic_type;
int32_t PicOrderCntVal;
uint8_t TemporalId;
} StdVideoEncodeH265ReferenceInfo;

View File

@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODECS_COMMON_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -19,7 +19,12 @@ extern "C" {
// vulkan_video_codecs_common is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codecs_common 1
#if !defined(VK_NO_STDINT_H)
#include <stdint.h>
#endif
#define VK_MAKE_VIDEO_STD_VERSION(major, minor, patch) \
((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))

View File

@ -2,7 +2,7 @@
#define VULKAN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_ANDROID_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -120,6 +120,32 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID(
struct AHardwareBuffer** pBuffer);
#endif
// VK_ANDROID_external_format_resolve is a preprocessor guard. Do not pass it to API calls.
#define VK_ANDROID_external_format_resolve 1
#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_SPEC_VERSION 1
#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_EXTENSION_NAME "VK_ANDROID_external_format_resolve"
typedef struct VkPhysicalDeviceExternalFormatResolveFeaturesANDROID {
VkStructureType sType;
void* pNext;
VkBool32 externalFormatResolve;
} VkPhysicalDeviceExternalFormatResolveFeaturesANDROID;
typedef struct VkPhysicalDeviceExternalFormatResolvePropertiesANDROID {
VkStructureType sType;
void* pNext;
VkBool32 nullColorAttachmentWithExternalFormatResolve;
VkChromaLocation externalFormatResolveChromaOffsetX;
VkChromaLocation externalFormatResolveChromaOffsetY;
} VkPhysicalDeviceExternalFormatResolvePropertiesANDROID;
typedef struct VkAndroidHardwareBufferFormatResolvePropertiesANDROID {
VkStructureType sType;
void* pNext;
VkFormat colorAttachmentFormat;
} VkAndroidHardwareBufferFormatResolvePropertiesANDROID;
#ifdef __cplusplus
}
#endif

View File

@ -2,7 +2,7 @@
#define VULKAN_BETA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -51,603 +51,6 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
// VK_KHR_video_encode_queue is a preprocessor guard. Do not pass it to API calls.
#define VK_KHR_video_encode_queue 1
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 10
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
typedef enum VkVideoEncodeTuningModeKHR {
VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1,
VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2,
VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3,
VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4,
VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeTuningModeKHR;
typedef VkFlags VkVideoEncodeFlagsKHR;
typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CAPABILITY_INSUFFICIENT_BITSTREAM_BUFFER_RANGE_DETECTION_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeCapabilityFlagBitsKHR;
typedef VkFlags VkVideoEncodeCapabilityFlagsKHR;
typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeRateControlModeFlagBitsKHR;
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeFeedbackFlagBitsKHR;
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
typedef enum VkVideoEncodeUsageFlagBitsKHR {
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008,
VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeUsageFlagBitsKHR;
typedef VkFlags VkVideoEncodeUsageFlagsKHR;
typedef enum VkVideoEncodeContentFlagBitsKHR {
VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeContentFlagBitsKHR;
typedef VkFlags VkVideoEncodeContentFlagsKHR;
typedef VkFlags VkVideoEncodeRateControlFlagsKHR;
typedef struct VkVideoEncodeInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFlagsKHR flags;
VkBuffer dstBuffer;
VkDeviceSize dstBufferOffset;
VkDeviceSize dstBufferRange;
VkVideoPictureResourceInfoKHR srcPictureResource;
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
uint32_t referenceSlotCount;
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
uint32_t precedingExternallyEncodedBytes;
} VkVideoEncodeInfoKHR;
typedef struct VkVideoEncodeCapabilitiesKHR {
VkStructureType sType;
void* pNext;
VkVideoEncodeCapabilityFlagsKHR flags;
VkVideoEncodeRateControlModeFlagsKHR rateControlModes;
uint32_t maxRateControlLayers;
uint64_t maxBitrate;
uint32_t maxQualityLevels;
VkExtent2D encodeInputPictureGranularity;
VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags;
} VkVideoEncodeCapabilitiesKHR;
typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR;
typedef struct VkVideoEncodeUsageInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeUsageFlagsKHR videoUsageHints;
VkVideoEncodeContentFlagsKHR videoContentHints;
VkVideoEncodeTuningModeKHR tuningMode;
} VkVideoEncodeUsageInfoKHR;
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
VkStructureType sType;
const void* pNext;
uint64_t averageBitrate;
uint64_t maxBitrate;
uint32_t frameRateNumerator;
uint32_t frameRateDenominator;
} VkVideoEncodeRateControlLayerInfoKHR;
typedef struct VkVideoEncodeRateControlInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeRateControlFlagsKHR flags;
VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode;
uint32_t layerCount;
const VkVideoEncodeRateControlLayerInfoKHR* pLayers;
uint32_t virtualBufferSizeInMs;
uint32_t initialVirtualBufferSizeInMs;
} VkVideoEncodeRateControlInfoKHR;
typedef struct VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR {
VkStructureType sType;
const void* pNext;
const VkVideoProfileInfoKHR* pVideoProfile;
uint32_t qualityLevel;
} VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR;
typedef struct VkVideoEncodeQualityLevelPropertiesKHR {
VkStructureType sType;
void* pNext;
VkVideoEncodeRateControlModeFlagBitsKHR preferredRateControlMode;
uint32_t preferredRateControlLayerCount;
} VkVideoEncodeQualityLevelPropertiesKHR;
typedef struct VkVideoEncodeQualityLevelInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t qualityLevel;
} VkVideoEncodeQualityLevelInfoKHR;
typedef struct VkVideoEncodeSessionParametersGetInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoSessionParametersKHR videoSessionParameters;
} VkVideoEncodeSessionParametersGetInfoKHR;
typedef struct VkVideoEncodeSessionParametersFeedbackInfoKHR {
VkStructureType sType;
void* pNext;
VkBool32 hasOverrides;
} VkVideoEncodeSessionParametersFeedbackInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo, VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties);
typedef VkResult (VKAPI_PTR *PFN_vkGetEncodedVideoSessionParametersKHR)(VkDevice device, const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo, VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo, size_t* pDataSize, void* pData);
typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo,
VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties);
VKAPI_ATTR VkResult VKAPI_CALL vkGetEncodedVideoSessionParametersKHR(
VkDevice device,
const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo,
VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo,
size_t* pDataSize,
void* pData);
VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
VkCommandBuffer commandBuffer,
const VkVideoEncodeInfoKHR* pEncodeInfo);
#endif
// VK_EXT_video_encode_h264 is a preprocessor guard. Do not pass it to API calls.
#define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 12
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H264_CAPABILITY_PER_SLICE_CONSTANT_QP_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef enum VkVideoEncodeH264StdFlagBitsEXT {
VK_VIDEO_ENCODE_H264_STD_SEPARATE_COLOR_PLANE_FLAG_SET_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_STD_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG_SET_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_STD_SCALING_MATRIX_PRESENT_FLAG_SET_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_STD_CHROMA_QP_INDEX_OFFSET_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H264_STD_SECOND_CHROMA_QP_INDEX_OFFSET_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H264_STD_PIC_INIT_QP_MINUS26_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H264_STD_WEIGHTED_PRED_FLAG_SET_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H264_STD_WEIGHTED_BIPRED_IDC_EXPLICIT_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H264_STD_WEIGHTED_BIPRED_IDC_IMPLICIT_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_STD_TRANSFORM_8X8_MODE_FLAG_SET_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H264_STD_DIRECT_SPATIAL_MV_PRED_FLAG_UNSET_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_UNSET_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_SET_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H264_STD_DIRECT_8X8_INFERENCE_FLAG_UNSET_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H264_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H264_STD_SLICE_QP_DELTA_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H264_STD_DIFFERENT_SLICE_QP_DELTA_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H264_STD_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264StdFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264StdFlagsEXT;
typedef enum VkVideoEncodeH264RateControlFlagBitsEXT {
VK_VIDEO_ENCODE_H264_RATE_CONTROL_ATTEMPT_HRD_COMPLIANCE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_REGULAR_GOP_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_TEMPORAL_LAYER_PATTERN_DYADIC_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264RateControlFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264RateControlFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH264CapabilityFlagsEXT flags;
StdVideoH264LevelIdc maxLevelIdc;
uint32_t maxSliceCount;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
uint32_t maxTemporalLayerCount;
VkBool32 expectDyadicTemporalLayerPattern;
int32_t minQp;
int32_t maxQp;
VkBool32 prefersGopRemainingFrames;
VkBool32 requiresGopRemainingFrames;
VkVideoEncodeH264StdFlagsEXT stdSyntaxFlags;
} VkVideoEncodeH264CapabilitiesEXT;
typedef struct VkVideoEncodeH264QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH264QpEXT;
typedef struct VkVideoEncodeH264QualityLevelPropertiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH264RateControlFlagsEXT preferredRateControlFlags;
uint32_t preferredGopFrameCount;
uint32_t preferredIdrPeriod;
uint32_t preferredConsecutiveBFrameCount;
uint32_t preferredTemporalLayerCount;
VkVideoEncodeH264QpEXT preferredConstantQp;
uint32_t preferredMaxL0ReferenceCount;
uint32_t preferredMaxL1ReferenceCount;
VkBool32 preferredStdEntropyCodingModeFlag;
} VkVideoEncodeH264QualityLevelPropertiesEXT;
typedef struct VkVideoEncodeH264SessionCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useMaxLevelIdc;
StdVideoH264LevelIdc maxLevelIdc;
} VkVideoEncodeH264SessionCreateInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdSPSCount;
const StdVideoH264SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH264PictureParameterSet* pStdPPSs;
} VkVideoEncodeH264SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersGetInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 writeStdSPS;
VkBool32 writeStdPPS;
uint32_t stdSPSId;
uint32_t stdPPSId;
} VkVideoEncodeH264SessionParametersGetInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersFeedbackInfoEXT {
VkStructureType sType;
void* pNext;
VkBool32 hasStdSPSOverrides;
VkBool32 hasStdPPSOverrides;
} VkVideoEncodeH264SessionParametersFeedbackInfoEXT;
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
VkStructureType sType;
const void* pNext;
int32_t constantQp;
const StdVideoEncodeH264SliceHeader* pStdSliceHeader;
} VkVideoEncodeH264NaluSliceInfoEXT;
typedef struct VkVideoEncodeH264PictureInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t naluSliceEntryCount;
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
const StdVideoEncodeH264PictureInfo* pStdPictureInfo;
VkBool32 generatePrefixNalu;
} VkVideoEncodeH264PictureInfoEXT;
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH264DpbSlotInfoEXT;
typedef struct VkVideoEncodeH264ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH264ProfileIdc stdProfileIdc;
} VkVideoEncodeH264ProfileInfoEXT;
typedef struct VkVideoEncodeH264RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
VkVideoEncodeH264RateControlFlagsEXT flags;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
uint32_t temporalLayerCount;
} VkVideoEncodeH264RateControlInfoEXT;
typedef struct VkVideoEncodeH264FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH264FrameSizeEXT;
typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useMinQp;
VkVideoEncodeH264QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH264QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH264FrameSizeEXT maxFrameSize;
} VkVideoEncodeH264RateControlLayerInfoEXT;
typedef struct VkVideoEncodeH264GopRemainingFrameInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useGopRemainingFrames;
uint32_t gopRemainingI;
uint32_t gopRemainingP;
uint32_t gopRemainingB;
} VkVideoEncodeH264GopRemainingFrameInfoEXT;
// VK_EXT_video_encode_h265 is a preprocessor guard. Do not pass it to API calls.
#define VK_EXT_video_encode_h265 1
#include "vk_video/vulkan_video_codec_h265std.h"
#include "vk_video/vulkan_video_codec_h265std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 12
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_SEGMENT_TYPE_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H265_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H265_CAPABILITY_PER_SLICE_SEGMENT_CONSTANT_QP_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILES_PER_SLICE_SEGMENT_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_SEGMENTS_PER_TILE_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT;
typedef enum VkVideoEncodeH265StdFlagBitsEXT {
VK_VIDEO_ENCODE_H265_STD_SEPARATE_COLOR_PLANE_FLAG_SET_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_STD_SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG_SET_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_STD_SCALING_LIST_DATA_PRESENT_FLAG_SET_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_STD_PCM_ENABLED_FLAG_SET_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_STD_SPS_TEMPORAL_MVP_ENABLED_FLAG_SET_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H265_STD_INIT_QP_MINUS26_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H265_STD_WEIGHTED_PRED_FLAG_SET_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H265_STD_WEIGHTED_BIPRED_FLAG_SET_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H265_STD_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H265_STD_SIGN_DATA_HIDING_ENABLED_FLAG_SET_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_SET_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_UNSET_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H265_STD_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG_SET_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H265_STD_TRANSQUANT_BYPASS_ENABLED_FLAG_SET_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H265_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H265_STD_ENTROPY_CODING_SYNC_ENABLED_FLAG_SET_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H265_STD_DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_SET_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG_SET_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENT_FLAG_SET_BIT_EXT = 0x00040000,
VK_VIDEO_ENCODE_H265_STD_SLICE_QP_DELTA_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H265_STD_DIFFERENT_SLICE_QP_DELTA_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H265_STD_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265StdFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265StdFlagsEXT;
typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CtbSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CtbSizeFlagsEXT;
typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT;
typedef enum VkVideoEncodeH265RateControlFlagBitsEXT {
VK_VIDEO_ENCODE_H265_RATE_CONTROL_ATTEMPT_HRD_COMPLIANCE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_TEMPORAL_SUB_LAYER_PATTERN_DYADIC_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265RateControlFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265RateControlFlagsEXT;
typedef struct VkVideoEncodeH265CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH265CapabilityFlagsEXT flags;
StdVideoH265LevelIdc maxLevelIdc;
uint32_t maxSliceSegmentCount;
VkExtent2D maxTiles;
VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes;
VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
uint32_t maxSubLayerCount;
VkBool32 expectDyadicTemporalSubLayerPattern;
int32_t minQp;
int32_t maxQp;
VkBool32 prefersGopRemainingFrames;
VkBool32 requiresGopRemainingFrames;
VkVideoEncodeH265StdFlagsEXT stdSyntaxFlags;
} VkVideoEncodeH265CapabilitiesEXT;
typedef struct VkVideoEncodeH265SessionCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useMaxLevelIdc;
StdVideoH265LevelIdc maxLevelIdc;
} VkVideoEncodeH265SessionCreateInfoEXT;
typedef struct VkVideoEncodeH265QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH265QpEXT;
typedef struct VkVideoEncodeH265QualityLevelPropertiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH265RateControlFlagsEXT preferredRateControlFlags;
uint32_t preferredGopFrameCount;
uint32_t preferredIdrPeriod;
uint32_t preferredConsecutiveBFrameCount;
uint32_t preferredSubLayerCount;
VkVideoEncodeH265QpEXT preferredConstantQp;
uint32_t preferredMaxL0ReferenceCount;
uint32_t preferredMaxL1ReferenceCount;
} VkVideoEncodeH265QualityLevelPropertiesEXT;
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdVPSCount;
const StdVideoH265VideoParameterSet* pStdVPSs;
uint32_t stdSPSCount;
const StdVideoH265SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH265PictureParameterSet* pStdPPSs;
} VkVideoEncodeH265SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdVPSCount;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH265SessionParametersGetInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 writeStdVPS;
VkBool32 writeStdSPS;
VkBool32 writeStdPPS;
uint32_t stdVPSId;
uint32_t stdSPSId;
uint32_t stdPPSId;
} VkVideoEncodeH265SessionParametersGetInfoEXT;
typedef struct VkVideoEncodeH265SessionParametersFeedbackInfoEXT {
VkStructureType sType;
void* pNext;
VkBool32 hasStdVPSOverrides;
VkBool32 hasStdSPSOverrides;
VkBool32 hasStdPPSOverrides;
} VkVideoEncodeH265SessionParametersFeedbackInfoEXT;
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
VkStructureType sType;
const void* pNext;
int32_t constantQp;
const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader;
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
typedef struct VkVideoEncodeH265PictureInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t naluSliceSegmentEntryCount;
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
const StdVideoEncodeH265PictureInfo* pStdPictureInfo;
} VkVideoEncodeH265PictureInfoEXT;
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH265DpbSlotInfoEXT;
typedef struct VkVideoEncodeH265ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH265ProfileIdc stdProfileIdc;
} VkVideoEncodeH265ProfileInfoEXT;
typedef struct VkVideoEncodeH265RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
VkVideoEncodeH265RateControlFlagsEXT flags;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
uint32_t subLayerCount;
} VkVideoEncodeH265RateControlInfoEXT;
typedef struct VkVideoEncodeH265FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH265FrameSizeEXT;
typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useMinQp;
VkVideoEncodeH265QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH265QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH265FrameSizeEXT maxFrameSize;
} VkVideoEncodeH265RateControlLayerInfoEXT;
typedef struct VkVideoEncodeH265GopRemainingFrameInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 useGopRemainingFrames;
uint32_t gopRemainingI;
uint32_t gopRemainingP;
uint32_t gopRemainingB;
} VkVideoEncodeH265GopRemainingFrameInfoEXT;
// VK_AMDX_shader_enqueue is a preprocessor guard. Do not pass it to API calls.
#define VK_AMDX_shader_enqueue 1
#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 1

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
#define VULKAN_DIRECTFB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_FUCHSIA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_GGP_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_IOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_MACOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

View File

@ -2,7 +2,7 @@
#define VULKAN_METAL_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@ -52,28 +52,28 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(
#define VK_EXT_metal_objects 1
#ifdef __OBJC__
@protocol MTLDevice;
typedef id<MTLDevice> MTLDevice_id;
typedef __unsafe_unretained id<MTLDevice> MTLDevice_id;
#else
typedef void* MTLDevice_id;
#endif
#ifdef __OBJC__
@protocol MTLCommandQueue;
typedef id<MTLCommandQueue> MTLCommandQueue_id;
typedef __unsafe_unretained id<MTLCommandQueue> MTLCommandQueue_id;
#else
typedef void* MTLCommandQueue_id;
#endif
#ifdef __OBJC__
@protocol MTLBuffer;
typedef id<MTLBuffer> MTLBuffer_id;
typedef __unsafe_unretained id<MTLBuffer> MTLBuffer_id;
#else
typedef void* MTLBuffer_id;
#endif
#ifdef __OBJC__
@protocol MTLTexture;
typedef id<MTLTexture> MTLTexture_id;
typedef __unsafe_unretained id<MTLTexture> MTLTexture_id;
#else
typedef void* MTLTexture_id;
#endif
@ -81,12 +81,12 @@ typedef void* MTLTexture_id;
typedef struct __IOSurface* IOSurfaceRef;
#ifdef __OBJC__
@protocol MTLSharedEvent;
typedef id<MTLSharedEvent> MTLSharedEvent_id;
typedef __unsafe_unretained id<MTLSharedEvent> MTLSharedEvent_id;
#else
typedef void* MTLSharedEvent_id;
#endif
#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1
#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 2
#define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects"
typedef enum VkExportMetalObjectTypeFlagBitsEXT {

Some files were not shown because too many files have changed in this diff Show More