pax_global_header00006660000000000000000000000064144023020060014501gustar00rootroot0000000000000052 comment=275e6459c7ab1ddd4b125f28d0440716e4888078 dxvk-0~git20230309.275e645/000077500000000000000000000000001440230200600146235ustar00rootroot00000000000000dxvk-0~git20230309.275e645/.editorconfig000066400000000000000000000004011440230200600172730ustar00rootroot00000000000000root = true [*] charset = utf-8 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true indent_style = tab indent_size = 8 max_line_length = 80 [*.py] indent_style = space indent_size = 4 [*.yml] indent_style = space indent_size = 2 dxvk-0~git20230309.275e645/.gitlab-ci.yml000066400000000000000000000057131440230200600172650ustar00rootroot00000000000000include: - project: 'freedesktop/ci-templates' ref: 3f37cc0e461f5b0c815409bf6f55759f26a74e9c file: - '/templates/ci-fairy.yml' - '/templates/alpine.yml' # When updating the prepare-container step, make sure to bump # FDO_DISTRIBUTION_TAG, otherwise the container won't get rebuilt. # To force a rebuild of the container, use: # $ git push -f -o ci.variable="FDO_FORCE_REBUILD=1" variables: FDO_UPSTREAM_REPO: 'emersion/libdisplay-info' FDO_DISTRIBUTION_TAG: '2022-10-18.3-hwdata' stages: - "Contribution checks" - "Prepare container" - "Build and test" check-mr: extends: .fdo.ci-fairy stage: "Contribution checks" script: - ci-fairy check-commits --signed-off-by - ci-fairy check-merge-request --require-allow-collaboration rules: - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"' when: always - when: never prepare-container: extends: .fdo.container-build@alpine@x86_64 stage: "Prepare container" variables: FDO_DISTRIBUTION_PACKAGES: | build-base clang compiler-rt meson make git gcovr py3-pygments go FDO_DISTRIBUTION_EXEC: | git clone git://linuxtv.org/edid-decode.git cd edid-decode git checkout f63a945936ae6ecf91349aa0984facfbc96173bf make make install cd .. rm -rf edid-decode go install git.sr.ht/~emersion/gyosu@latest mv ~/go/bin/gyosu /usr/bin/ rm -rf ~/go git clone https://github.com/vcrhonek/hwdata.git cd hwdata ./configure --disable-blacklist make install cd .. rm -rf hwdata rules: - when: on_success build-gcc: extends: .fdo.distribution-image@alpine stage: "Build and test" script: - CC=gcc meson setup build/ --fatal-meson-warnings -Dwerror=true -Db_coverage=true - ninja -C build/ - ninja -C build/ test - ninja -C build/ -j1 coverage-xml coverage-html artifacts: when: always paths: - build/meson-logs/ reports: junit: build/meson-logs/testlog.junit.xml coverage_report: coverage_format: cobertura path: build/meson-logs/coverage.xml rules: - when: on_success build-clang: extends: .fdo.distribution-image@alpine stage: "Build and test" script: - CC=clang meson setup build/ --fatal-meson-warnings -Dwerror=true -Db_sanitize=address,undefined -Db_lundef=false - ninja -C build/ - ninja -C build/ test artifacts: when: always paths: - build/meson-logs/ reports: junit: build/meson-logs/testlog.junit.xml rules: - when: on_success pages: extends: .fdo.distribution-image@alpine stage: "Build and test" script: - gyosu -I$PWD/include/ -fexported-symbols='di_*' -ffile-prefix-map=$PWD/include/= -fsite-name=libdisplay-info -o public $PWD/include/libdisplay-info/ artifacts: paths: - public/ rules: - if: '$CI_PROJECT_PATH == "emersion/libdisplay-info" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' when: on_success - when: never dxvk-0~git20230309.275e645/LICENSE000066400000000000000000000021011440230200600156220ustar00rootroot00000000000000MIT License Copyright (c) 2022 The libdisplay-info Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dxvk-0~git20230309.275e645/README.md000066400000000000000000000056741440230200600161160ustar00rootroot00000000000000# libdisplay-info EDID and DisplayID library. Goals: - Provide a set of high-level, easy-to-use, opinionated functions as well as low-level functions to access detailed information. - Simplicity and correctness over performance and resource usage. - Well-tested and fuzzed. Documentation is available on the [website]. ## Using The public API headers are categorised as either high-level or low-level API as per the comments in the header files. Users of libdisplay-info should prefer high-level API over low-level API when possible. If high-level API lacks needed features, please propose additions to the high-level API upstream before using low-level API to get what you need. If the additions are rejected, you are welcome to use the low-level API. This policy is aimed to propagate best practises when interpreting EDID and DisplayID information which can often be cryptic or even inconsistent. ## Contributing Open issues and merge requests on the [GitLab project]. In general, the [Wayland contribution guidelines] should be followed. In particular, each commit must carry a Signed-off-by tag to denote that the submitter adheres to the [Developer Certificate of Origin 1.1]. This project follows the [freedesktop.org Contributor Covenant]. ## Building libdisplay-info has the following dependencies: - [hwdata](https://github.com/vcrhonek/hwdata) for the PNP ID database used at build-time only. libdisplay-info is built using [Meson]: meson setup build/ ninja -C build/ ## Testing The low-level EDID library is tested against [edid-decode]. `test/data/` contains a small collection of EDID blobs and diffs between upstream `edid-decode` and our `di-edid-decode` clone. Our CI ensures the diffs are up-to-date. A patch should never make the diffs grow larger. To add a new EDID blob or update a diff, use `test/edid-decode-diff.sh test/data/`. To run the test suite locally, you need to use [edid-decode] of the git revision mentioned in `.gitlab-ci.yml`. Otherwise you may experience false failures. The latest code coverage report is available on [GitLab CI][coverage]. ## Fuzzing To fuzz libdisplay-info with [AFL], the library needs to be instrumented: CC=afl-gcc meson build/ ninja -C build/ afl-fuzz -i test/data/ -o afl/ build/di-edid-decode [website]: https://emersion.pages.freedesktop.org/libdisplay-info/ [GitLab project]: https://gitlab.freedesktop.org/emersion/libdisplay-info [Wayland contribution guidelines]: https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/CONTRIBUTING.md [Developer Certificate of Origin 1.1]: https://developercertificate.org/ [freedesktop.org Contributor Covenant]: https://www.freedesktop.org/wiki/CodeOfConduct/ [Meson]: https://mesonbuild.com/ [coverage]: https://gitlab.freedesktop.org/emersion/libdisplay-info/-/jobs/artifacts/main/file/build/meson-logs/coveragereport/index.html?job=build-gcc [edid-decode]: https://git.linuxtv.org/edid-decode.git/ [AFL]: https://lcamtuf.coredump.cx/afl/ dxvk-0~git20230309.275e645/cta.c000066400000000000000000000340751440230200600155470ustar00rootroot00000000000000#include #include #include #include #include #include #include "bits.h" #include "cta.h" #include "log.h" #include "edid.h" /** * Number of bytes in the CTA header (tag + revision + DTD offset + flags). */ #define CTA_HEADER_SIZE 4 /** * Exclusive upper bound for the detailed timing definitions in the CTA block. */ #define CTA_DTD_END 127 static void add_failure(struct di_edid_cta *cta, const char fmt[], ...) { va_list args; va_start(args, fmt); _di_logger_va_add_failure(cta->logger, fmt, args); va_end(args); } static void add_failure_until(struct di_edid_cta *cta, int revision, const char fmt[], ...) { va_list args; if (cta->revision > revision) { return; } va_start(args, fmt); _di_logger_va_add_failure(cta->logger, fmt, args); va_end(args); } static bool parse_video_block(struct di_edid_cta *cta, struct di_cta_video_block *video, const uint8_t *data, size_t size) { size_t i; uint8_t raw; struct di_cta_svd svd, *svd_ptr; if (size == 0) add_failure(cta, "Video Data Block: Empty Data Block"); for (i = 0; i < size; i++) { raw = data[i]; if (raw == 0 || raw == 128 || raw >= 254) { /* Reserved */ add_failure_until(cta, 3, "Video Data Block: Unknown VIC %" PRIu8 ".", raw); continue; } else if (raw <= 127 || raw >= 193) { svd = (struct di_cta_svd) { .vic = raw, }; } else { svd = (struct di_cta_svd) { .vic = get_bit_range(raw, 6, 0), .native = true, }; } svd_ptr = calloc(1, sizeof(*svd_ptr)); if (!svd_ptr) return false; *svd_ptr = svd; assert(video->svds_len < EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES); video->svds[video->svds_len++] = svd_ptr; } return true; } static bool parse_video_cap_block(struct di_edid_cta *cta, struct di_cta_video_cap_block *video_cap, const uint8_t *data, size_t size) { if (size < 1) { add_failure(cta, "Video Capability Data Block: Empty Data Block with length %u.", size); return false; } video_cap->selectable_ycc_quantization_range = has_bit(data[0], 7); video_cap->selectable_rgb_quantization_range = has_bit(data[0], 6); video_cap->pt_over_underscan = get_bit_range(data[0], 5, 4); video_cap->it_over_underscan = get_bit_range(data[0], 3, 2); video_cap->ce_over_underscan = get_bit_range(data[0], 1, 0); if (!video_cap->selectable_rgb_quantization_range && cta->revision >= 3) add_failure(cta, "Video Capability Data Block: Set Selectable RGB Quantization to avoid interop issues."); /* TODO: add failure if selectable_ycc_quantization_range is unset, * the sink supports YCbCr formats and the revision is 3+ */ switch (video_cap->it_over_underscan) { case DI_CTA_VIDEO_CAP_ALWAYS_OVERSCAN: if (cta->flags.it_underscan) add_failure(cta, "Video Capability Data Block: IT video formats are always overscanned, but bit 7 of Byte 3 of the CTA-861 Extension header is set to underscanned."); break; case DI_CTA_VIDEO_CAP_ALWAYS_UNDERSCAN: if (!cta->flags.it_underscan) add_failure(cta, "Video Capability Data Block: IT video formats are always underscanned, but bit 7 of Byte 3 of the CTA-861 Extension header is set to overscanned."); default: break; } return true; } static bool parse_colorimetry_block(struct di_edid_cta *cta, struct di_cta_colorimetry_block *colorimetry, const uint8_t *data, size_t size) { if (size < 2) { add_failure(cta, "Colorimetry Data Block: Empty Data Block with length %u.", size); return false; } colorimetry->bt2020_rgb = has_bit(data[0], 7); colorimetry->bt2020_ycc = has_bit(data[0], 6); colorimetry->bt2020_cycc = has_bit(data[0], 5); colorimetry->oprgb = has_bit(data[0], 4); colorimetry->opycc_601 = has_bit(data[0], 3); colorimetry->sycc_601 = has_bit(data[0], 2); colorimetry->xvycc_709 = has_bit(data[0], 1); colorimetry->xvycc_601 = has_bit(data[0], 0); colorimetry->st2113_rgb = has_bit(data[1], 7); colorimetry->ictcp = has_bit(data[1], 6); if (get_bit_range(data[1], 5, 0) != 0) add_failure_until(cta, 3, "Colorimetry Data Block: Reserved bits MD0-MD3 must be 0."); return true; } static float parse_max_luminance(uint8_t raw) { if (raw == 0) return 0; return 50 * powf(2, (float) raw / 32); } static float parse_min_luminance(uint8_t raw, float max) { if (raw == 0) return 0; return max * powf((float) raw / 255, 2) / 100; } static bool parse_hdr_static_metadata_block(struct di_edid_cta *cta, struct di_cta_hdr_static_metadata_block_priv *metadata, const uint8_t *data, size_t size) { uint8_t eotfs, descriptors; if (size < 2) { add_failure(cta, "HDR Static Metadata Data Block: Empty Data Block with length %u.", size); return false; } metadata->base.eotfs = &metadata->eotfs; metadata->base.descriptors = &metadata->descriptors; eotfs = data[0]; metadata->eotfs.traditional_sdr = has_bit(eotfs, 0); metadata->eotfs.traditional_hdr = has_bit(eotfs, 1); metadata->eotfs.pq = has_bit(eotfs, 2); metadata->eotfs.hlg = has_bit(eotfs, 3); if (get_bit_range(eotfs, 7, 4)) add_failure_until(cta, 3, "HDR Static Metadata Data Block: Unknown EOTF."); descriptors = data[1]; metadata->descriptors.type1 = has_bit(descriptors, 0); if (get_bit_range(descriptors, 7, 1)) add_failure_until(cta, 3, "HDR Static Metadata Data Block: Unknown descriptor type."); if (size > 2) metadata->base.desired_content_max_luminance = parse_max_luminance(data[2]); if (size > 3) metadata->base.desired_content_max_frame_avg_luminance = parse_max_luminance(data[3]); if (size > 4) { if (metadata->base.desired_content_max_luminance == 0) add_failure(cta, "HDR Static Metadata Data Block: Desired content min luminance is set, but max luminance is unset."); else metadata->base.desired_content_min_luminance = parse_min_luminance(data[4], metadata->base.desired_content_max_luminance); } return true; } static bool parse_vesa_transfer_characteristics_block(struct di_edid_cta *cta, struct di_cta_vesa_transfer_characteristics *tf, const uint8_t *data, size_t size) { size_t i; if (size != 7 && size != 15 && size != 31) { add_failure(cta, "Invalid length %u.", size); return false; } tf->points_len = (uint8_t) size + 1; tf->usage = get_bit_range(data[0], 7, 6); tf->points[0] = get_bit_range(data[0], 5, 0) / 1023.0f; for (i = 1; i < size; i++) tf->points[i] = tf->points[i - 1] + data[i] / 1023.0f; tf->points[i] = 1.0f; return true; } static void destroy_data_block(struct di_cta_data_block *data_block) { size_t i; struct di_cta_video_block *video; switch (data_block->tag) { case DI_CTA_DATA_BLOCK_VIDEO: video = &data_block->video; for (i = 0; i < video->svds_len; i++) free(video->svds[i]); break; default: break; /* Nothing to do */ } free(data_block); } static bool parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data, size_t size) { enum di_cta_data_block_tag tag; uint8_t extended_tag; struct di_cta_data_block *data_block; data_block = calloc(1, sizeof(*data_block)); if (!data_block) { return false; } switch (raw_tag) { case 1: tag = DI_CTA_DATA_BLOCK_AUDIO; break; case 2: tag = DI_CTA_DATA_BLOCK_VIDEO; if (!parse_video_block(cta, &data_block->video, data, size)) goto error; break; case 3: /* Vendor-Specific Data Block */ goto skip; case 4: tag = DI_CTA_DATA_BLOCK_SPEAKER_ALLOC; break; case 5: tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC; if (!parse_vesa_transfer_characteristics_block(cta, &data_block->vesa_transfer_characteristics, data, size)) goto error; break; case 7: /* Use Extended Tag */ if (size < 1) { add_failure(cta, "Empty block with extended tag."); goto skip; } extended_tag = data[0]; data = &data[1]; size--; switch (extended_tag) { case 0: tag = DI_CTA_DATA_BLOCK_VIDEO_CAP; if (!parse_video_cap_block(cta, &data_block->video_cap, data, size)) goto skip; break; case 2: tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE; break; case 5: tag = DI_CTA_DATA_BLOCK_COLORIMETRY; if (!parse_colorimetry_block(cta, &data_block->colorimetry, data, size)) goto skip; break; case 6: tag = DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA; if (!parse_hdr_static_metadata_block(cta, &data_block->hdr_static_metadata, data, size)) goto skip; break; case 7: tag = DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA; break; case 13: tag = DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF; break; case 14: tag = DI_CTA_DATA_BLOCK_YCBCR420; break; case 15: tag = DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP; break; case 18: tag = DI_CTA_DATA_BLOCK_HDMI_AUDIO; break; case 19: tag = DI_CTA_DATA_BLOCK_ROOM_CONFIG; break; case 20: tag = DI_CTA_DATA_BLOCK_SPEAKER_LOCATION; break; case 32: tag = DI_CTA_DATA_BLOCK_INFOFRAME; break; case 34: tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII; break; case 35: tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VIII; break; case 42: tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_X; break; case 120: tag = DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE; break; case 121: tag = DI_CTA_DATA_BLOCK_HDMI_SINK_CAP; break; case 1: /* Vendor-Specific Video Data Block */ case 17: /* Vendor-Specific Audio Data Block */ goto skip; default: /* Reserved */ add_failure_until(cta, 3, "Unknown CTA-861 Data Block (extended tag 0x"PRIx8", length %zu).", extended_tag, size); goto skip; } break; default: /* Reserved */ add_failure_until(cta, 3, "Unknown CTA-861 Data Block (tag 0x"PRIx8", length %zu).", raw_tag, size); goto skip; } data_block->tag = tag; assert(cta->data_blocks_len < EDID_CTA_MAX_DATA_BLOCKS); cta->data_blocks[cta->data_blocks_len++] = data_block; return true; skip: free(data_block); return true; error: destroy_data_block(data_block); return false; } bool _di_edid_cta_parse(struct di_edid_cta *cta, const uint8_t *data, size_t size, struct di_logger *logger) { uint8_t flags, dtd_start; uint8_t data_block_header, data_block_tag, data_block_size; size_t i; struct di_edid_detailed_timing_def_priv *detailed_timing_def; assert(size == 128); assert(data[0] == 0x02); cta->logger = logger; cta->revision = data[1]; dtd_start = data[2]; flags = data[3]; if (cta->revision >= 2) { cta->flags.it_underscan = has_bit(flags, 7); cta->flags.basic_audio = has_bit(flags, 6); cta->flags.ycc444 = has_bit(flags, 5); cta->flags.ycc422 = has_bit(flags, 4); cta->flags.native_dtds = get_bit_range(flags, 3, 0); } else if (flags != 0) { /* Reserved */ add_failure(cta, "Non-zero byte 3."); } if (dtd_start == 0) { return true; } else if (dtd_start < CTA_HEADER_SIZE || dtd_start >= size) { errno = EINVAL; return false; } i = CTA_HEADER_SIZE; while (i < dtd_start) { data_block_header = data[i]; data_block_tag = get_bit_range(data_block_header, 7, 5); data_block_size = get_bit_range(data_block_header, 4, 0); if (i + 1 + data_block_size > dtd_start) { _di_edid_cta_finish(cta); errno = EINVAL; return false; } if (!parse_data_block(cta, data_block_tag, &data[i + 1], data_block_size)) { _di_edid_cta_finish(cta); return false; } i += 1 + data_block_size; } if (i != dtd_start) add_failure(cta, "Offset is %"PRIu8", but should be %zu.", dtd_start, i); for (i = dtd_start; i + EDID_BYTE_DESCRIPTOR_SIZE <= CTA_DTD_END; i += EDID_BYTE_DESCRIPTOR_SIZE) { if (data[i] == 0) break; detailed_timing_def = _di_edid_parse_detailed_timing_def(&data[i]); if (!detailed_timing_def) { _di_edid_cta_finish(cta); return false; } assert(cta->detailed_timing_defs_len < EDID_CTA_MAX_DETAILED_TIMING_DEFS); cta->detailed_timing_defs[cta->detailed_timing_defs_len++] = detailed_timing_def; } /* All padding bytes after the last DTD must be zero */ while (i < CTA_DTD_END) { if (data[i] != 0) { add_failure(cta, "Padding: Contains non-zero bytes."); break; } i++; } cta->logger = NULL; return true; } void _di_edid_cta_finish(struct di_edid_cta *cta) { size_t i; for (i = 0; i < cta->data_blocks_len; i++) { destroy_data_block(cta->data_blocks[i]); } for (i = 0; i < cta->detailed_timing_defs_len; i++) { free(cta->detailed_timing_defs[i]); } } int di_edid_cta_get_revision(const struct di_edid_cta *cta) { return cta->revision; } const struct di_edid_cta_flags * di_edid_cta_get_flags(const struct di_edid_cta *cta) { return &cta->flags; } const struct di_cta_data_block *const * di_edid_cta_get_data_blocks(const struct di_edid_cta *cta) { return (const struct di_cta_data_block *const *) cta->data_blocks; } enum di_cta_data_block_tag di_cta_data_block_get_tag(const struct di_cta_data_block *block) { return block->tag; } const struct di_cta_svd *const * di_cta_data_block_get_svds(const struct di_cta_data_block *block) { if (block->tag != DI_CTA_DATA_BLOCK_VIDEO) { return NULL; } return (const struct di_cta_svd *const *) block->video.svds; } const struct di_cta_colorimetry_block * di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block) { if (block->tag != DI_CTA_DATA_BLOCK_COLORIMETRY) { return NULL; } return &block->colorimetry; } const struct di_cta_hdr_static_metadata_block * di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block) { if (block->tag != DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA) { return NULL; } return &block->hdr_static_metadata.base; } const struct di_cta_video_cap_block * di_cta_data_block_get_video_cap(const struct di_cta_data_block *block) { if (block->tag != DI_CTA_DATA_BLOCK_VIDEO_CAP) { return NULL; } return &block->video_cap; } const struct di_edid_detailed_timing_def *const * di_edid_cta_get_detailed_timing_defs(const struct di_edid_cta *cta) { return (const struct di_edid_detailed_timing_def *const *) cta->detailed_timing_defs; } const struct di_cta_vesa_transfer_characteristics * di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block *block) { if (block->tag != DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC) { return NULL; } return &block->vesa_transfer_characteristics; } dxvk-0~git20230309.275e645/di-edid-decode/000077500000000000000000000000001440230200600173435ustar00rootroot00000000000000dxvk-0~git20230309.275e645/di-edid-decode/cta.c000066400000000000000000000216331440230200600202630ustar00rootroot00000000000000#include #include #include #include #include #include "di-edid-decode.h" static void printf_cta_svds(const struct di_cta_svd *const *svds) { size_t i; const struct di_cta_svd *svd; for (i = 0; svds[i] != NULL; i++) { svd = svds[i]; printf(" VIC %3" PRIu8, svd->vic); if (svd->native) printf(" (native)"); printf("\n"); // TODO: print detailed mode info } } static uint8_t encode_max_luminance(float max) { if (max == 0) return 0; return (uint8_t) (log2f(max / 50) * 32); } static uint8_t encode_min_luminance(float min, float max) { if (min == 0) return 0; return (uint8_t) (255 * sqrtf(min / max * 100)); } static void print_cta_hdr_static_metadata(const struct di_cta_hdr_static_metadata_block *metadata) { printf(" Electro optical transfer functions:\n"); if (metadata->eotfs->traditional_sdr) printf(" Traditional gamma - SDR luminance range\n"); if (metadata->eotfs->traditional_hdr) printf(" Traditional gamma - HDR luminance range\n"); if (metadata->eotfs->pq) printf(" SMPTE ST2084\n"); if (metadata->eotfs->hlg) printf(" Hybrid Log-Gamma\n"); printf(" Supported static metadata descriptors:\n"); if (metadata->descriptors->type1) printf(" Static metadata type 1\n"); /* TODO: figure out a way to print raw values? */ if (metadata->desired_content_max_luminance != 0) printf(" Desired content max luminance: %" PRIu8 " (%.3f cd/m^2)\n", encode_max_luminance(metadata->desired_content_max_luminance), metadata->desired_content_max_luminance); if (metadata->desired_content_max_frame_avg_luminance != 0) printf(" Desired content max frame-average luminance: %" PRIu8 " (%.3f cd/m^2)\n", encode_max_luminance(metadata->desired_content_max_frame_avg_luminance), metadata->desired_content_max_frame_avg_luminance); if (metadata->desired_content_min_luminance != 0) printf(" Desired content min luminance: %" PRIu8 " (%.3f cd/m^2)\n", encode_min_luminance(metadata->desired_content_min_luminance, metadata->desired_content_max_luminance), metadata->desired_content_min_luminance); } static void print_cta_vesa_transfer_characteristics(const struct di_cta_vesa_transfer_characteristics *tf) { size_t i; switch (tf->usage) { case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_WHITE: printf(" White"); break; case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_RED: printf(" Red"); break; case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_GREEN: printf(" Green"); break; case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_BLUE: printf(" Blue"); break; } printf(" transfer characteristics:"); for (i = 0; i < tf->points_len; i++) printf(" %u", (uint16_t) roundf(tf->points[i] * 1023.0f)); printf("\n"); uncommon_features.cta_transfer_characteristics = true; } static const char * cta_data_block_tag_name(enum di_cta_data_block_tag tag) { switch (tag) { case DI_CTA_DATA_BLOCK_AUDIO: return "Audio Data Block"; case DI_CTA_DATA_BLOCK_VIDEO: return "Video Data Block"; case DI_CTA_DATA_BLOCK_SPEAKER_ALLOC: return "Speaker Allocation Data Block"; case DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC: return "VESA Display Transfer Characteristics Data Block"; case DI_CTA_DATA_BLOCK_VIDEO_CAP: return "Video Capability Data Block"; case DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE: return "VESA Video Display Device Data Block"; case DI_CTA_DATA_BLOCK_COLORIMETRY: return "Colorimetry Data Block"; case DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA: return "HDR Static Metadata Data Block"; case DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA: return "HDR Dynamic Metadata Data Block"; case DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF: return "Video Format Preference Data Block"; case DI_CTA_DATA_BLOCK_YCBCR420: return "YCbCr 4:2:0 Video Data Block"; case DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP: return "YCbCr 4:2:0 Capability Map Data Block"; case DI_CTA_DATA_BLOCK_HDMI_AUDIO: return "HDMI Audio Data Block"; case DI_CTA_DATA_BLOCK_ROOM_CONFIG: return "Room Configuration Data Block"; case DI_CTA_DATA_BLOCK_SPEAKER_LOCATION: return "Speaker Location Data Block"; case DI_CTA_DATA_BLOCK_INFOFRAME: return "InfoFrame Data Block"; case DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII: return "DisplayID Type VII Video Timing Data Block"; case DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VIII: return "DisplayID Type VIII Video Timing Data Block"; case DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_X: return "DisplayID Type X Video Timing Data Block"; case DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE : return "HDMI Forum EDID Extension Override Data Block"; case DI_CTA_DATA_BLOCK_HDMI_SINK_CAP: return "HDMI Forum Sink Capability Data Block"; } return "Unknown CTA-861 Data Block"; } static const char * video_cap_over_underscan_name(enum di_cta_video_cap_over_underscan over_underscan, const char *unknown) { switch (over_underscan) { case DI_CTA_VIDEO_CAP_UNKNOWN_OVER_UNDERSCAN: return unknown; case DI_CTA_VIDEO_CAP_ALWAYS_OVERSCAN: return "Always Overscanned"; case DI_CTA_VIDEO_CAP_ALWAYS_UNDERSCAN: return "Always Underscanned"; case DI_CTA_VIDEO_CAP_BOTH_OVER_UNDERSCAN: return "Supports both over- and underscan"; } abort(); } void print_cta(const struct di_edid_cta *cta) { const struct di_edid_cta_flags *cta_flags; const struct di_cta_data_block *const *data_blocks; const struct di_cta_data_block *data_block; enum di_cta_data_block_tag data_block_tag; const struct di_cta_svd *const *svds; const struct di_cta_video_cap_block *video_cap; const struct di_cta_colorimetry_block *colorimetry; const struct di_cta_hdr_static_metadata_block *hdr_static_metadata; const struct di_cta_vesa_transfer_characteristics *transfer_characteristics; size_t i; const struct di_edid_detailed_timing_def *const *detailed_timing_defs; printf(" Revision: %d\n", di_edid_cta_get_revision(cta)); cta_flags = di_edid_cta_get_flags(cta); if (cta_flags->it_underscan) { printf(" Underscans IT Video Formats by default\n"); } if (cta_flags->basic_audio) { printf(" Basic audio support\n"); } if (cta_flags->ycc444) { printf(" Supports YCbCr 4:4:4\n"); } if (cta_flags->ycc422) { printf(" Supports YCbCr 4:2:2\n"); } printf(" Native detailed modes: %d\n", cta_flags->native_dtds); data_blocks = di_edid_cta_get_data_blocks(cta); for (i = 0; data_blocks[i] != NULL; i++) { data_block = data_blocks[i]; data_block_tag = di_cta_data_block_get_tag(data_block); printf(" %s:\n", cta_data_block_tag_name(data_block_tag)); switch (data_block_tag) { case DI_CTA_DATA_BLOCK_VIDEO: svds = di_cta_data_block_get_svds(data_block); printf_cta_svds(svds); break; case DI_CTA_DATA_BLOCK_VIDEO_CAP: video_cap = di_cta_data_block_get_video_cap(data_block); printf(" YCbCr quantization: %s\n", video_cap->selectable_ycc_quantization_range ? "Selectable (via AVI YQ)" : "No Data"); printf(" RGB quantization: %s\n", video_cap->selectable_ycc_quantization_range ? "Selectable (via AVI Q)" : "No Data"); printf(" PT scan behavior: %s\n", video_cap_over_underscan_name(video_cap->pt_over_underscan, "No Data")); printf(" IT scan behavior: %s\n", video_cap_over_underscan_name(video_cap->it_over_underscan, "IT video formats not supported")); printf(" CE scan behavior: %s\n", video_cap_over_underscan_name(video_cap->ce_over_underscan, "CE video formats not supported")); break; case DI_CTA_DATA_BLOCK_COLORIMETRY: colorimetry = di_cta_data_block_get_colorimetry(data_block); if (colorimetry->xvycc_601) printf(" xvYCC601\n"); if (colorimetry->xvycc_709) printf(" xvYCC709\n"); if (colorimetry->sycc_601) printf(" sYCC601\n"); if (colorimetry->opycc_601) printf(" opYCC601\n"); if (colorimetry->oprgb) printf(" opRGB\n"); if (colorimetry->bt2020_cycc) printf(" BT2020cYCC\n"); if (colorimetry->bt2020_ycc) printf(" BT2020YCC\n"); if (colorimetry->bt2020_rgb) printf(" BT2020RGB\n"); if (colorimetry->ictcp) printf(" ICtCp\n"); if (colorimetry->st2113_rgb) printf(" ST2113RGB\n"); break; case DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA: hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(data_block); print_cta_hdr_static_metadata(hdr_static_metadata); break; case DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC: transfer_characteristics = di_cta_data_block_get_vesa_transfer_characteristics(data_block); print_cta_vesa_transfer_characteristics(transfer_characteristics); break; default: break; /* Ignore */ } } detailed_timing_defs = di_edid_cta_get_detailed_timing_defs(cta); if (detailed_timing_defs[0]) { printf(" Detailed Timing Descriptors:\n"); } for (i = 0; detailed_timing_defs[i] != NULL; i++) { print_detailed_timing_def(detailed_timing_defs[i]); } } dxvk-0~git20230309.275e645/di-edid-decode/displayid.c000066400000000000000000000220741440230200600214760ustar00rootroot00000000000000#include #include #include #include "di-edid-decode.h" static bool is_displayid_base_block = true; static void print_displayid_display_params(const struct di_displayid_display_params *params) { printf(" Image size: %.1f mm x %.1f mm\n", params->horiz_image_mm, params->vert_image_mm); printf(" Display native pixel format: %dx%d\n", params->horiz_pixels, params->vert_pixels); printf(" Feature support flags:\n"); if (params->features->audio) printf(" Audio support on video interface\n"); if (params->features->separate_audio_inputs) printf(" Separate audio inputs provided\n"); if (params->features->audio_input_override) printf(" Audio input override\n"); if (params->features->power_management) printf(" Power management (DPM)\n"); if (params->features->fixed_timing) printf(" Fixed timing\n"); if (params->features->fixed_pixel_format) printf(" Fixed pixel format\n"); if (params->features->ai) printf(" Support ACP, ISRC1, or ISRC2packets\n"); if (params->features->deinterlacing) printf(" De-interlacing\n"); if (params->gamma != 0) printf(" Gamma: %.2f\n", params->gamma); printf(" Aspect ratio: %.2f\n", params->aspect_ratio); printf(" Dynamic bpc native: %d\n", params->bits_per_color_native); printf(" Dynamic bpc overall: %d\n", params->bits_per_color_overall); } static void get_displayid_type_i_timing_aspect_ratio(enum di_displayid_type_i_timing_aspect_ratio ratio, int *horiz, int *vert) { switch (ratio) { case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_1_1: *horiz = *vert = 1; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_5_4: *horiz = 5; *vert = 4; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_4_3: *horiz = 4; *vert = 3; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_15_9: *horiz = 15; *vert = 9; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_9: *horiz = 16; *vert = 9; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_10: *horiz = 16; *vert = 10; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_64_27: *horiz = 64; *vert = 27; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_256_135: *horiz = 256; *vert = 135; return; case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_UNDEFINED: *horiz = *vert = 0; return; } abort(); /* Unreachable */ } static const char * displayid_type_i_timing_stereo_3d_name(enum di_displayid_type_i_timing_stereo_3d stereo_3d) { switch (stereo_3d) { case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_NEVER: return "no 3D stereo"; case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_ALWAYS: return "3D stereo"; case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_USER: return "3D stereo depends on user action"; } abort(); /* Unreachable */ } static const char * displayid_type_i_timing_sync_polarity_name(enum di_displayid_type_i_timing_sync_polarity pol) { switch (pol) { case DI_DISPLAYID_TYPE_I_TIMING_SYNC_NEGATIVE: return "N"; case DI_DISPLAYID_TYPE_I_TIMING_SYNC_POSITIVE: return "P"; } abort(); /* Unreachable */ } static void print_displayid_type_i_timing(const struct di_displayid_type_i_timing *t) { int horiz_total, vert_total; int horiz_back_porch, vert_back_porch; int horiz_ratio, vert_ratio; double pixel_clock_hz, refresh, horiz_freq_hz; get_displayid_type_i_timing_aspect_ratio(t->aspect_ratio, &horiz_ratio, &vert_ratio); horiz_total = t->horiz_active + t->horiz_blank; vert_total = t->vert_active + t->vert_blank; pixel_clock_hz = t->pixel_clock_mhz * 1000 * 1000; refresh = pixel_clock_hz / (horiz_total * vert_total); horiz_freq_hz = pixel_clock_hz / horiz_total; printf(" DTD:"); printf(" %5dx%-5d", t->horiz_active, t->vert_active); if (t->interlaced) { printf("i"); } printf(" %10.6f Hz", refresh); printf(" %3d:%-3d", horiz_ratio, vert_ratio); printf(" %8.3f kHz %13.6f MHz", horiz_freq_hz / 1000, t->pixel_clock_mhz); printf(" (aspect "); if (t->aspect_ratio == DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_UNDEFINED) printf("undefined"); else printf("%d:%d", horiz_ratio, vert_ratio); printf(", %s", displayid_type_i_timing_stereo_3d_name(t->stereo_3d)); if (t->preferred) printf(", preferred"); printf(")\n"); horiz_back_porch = t->horiz_blank - t->horiz_sync_width - t->horiz_offset; printf(" Hfront %4d Hsync %3d Hback %4d Hpol %s", t->horiz_offset, t->horiz_sync_width, horiz_back_porch, displayid_type_i_timing_sync_polarity_name(t->horiz_sync_polarity)); printf("\n"); vert_back_porch = t->vert_blank - t->vert_sync_width - t->vert_offset; printf(" Vfront %4d Vsync %3d Vback %4d Vpol %s", t->vert_offset, t->vert_sync_width, vert_back_porch, displayid_type_i_timing_sync_polarity_name(t->vert_sync_polarity)); printf("\n"); } static void print_displayid_type_i_timing_block(const struct di_displayid_data_block *data_block) { size_t i; const struct di_displayid_type_i_timing *const *timings; timings = di_displayid_data_block_get_type_i_timings(data_block); for (i = 0; timings[i] != NULL; i++) print_displayid_type_i_timing(timings[i]); } static const char * displayid_product_type_name(enum di_displayid_product_type type) { switch (type) { case DI_DISPLAYID_PRODUCT_TYPE_EXTENSION: return "Extension Section"; case DI_DISPLAYID_PRODUCT_TYPE_TEST: return "Test Structure; test equipment only"; case DI_DISPLAYID_PRODUCT_TYPE_DISPLAY_PANEL: return "Display panel or other transducer, LCD or PDP module, etc."; case DI_DISPLAYID_PRODUCT_TYPE_STANDALONE_DISPLAY: return "Standalone display device"; case DI_DISPLAYID_PRODUCT_TYPE_TV_RECEIVER: return "Television receiver"; case DI_DISPLAYID_PRODUCT_TYPE_REPEATER: return "Repeater/translator"; case DI_DISPLAYID_PRODUCT_TYPE_DIRECT_DRIVE: return "DIRECT DRIVE monitor"; } abort(); } static const char * displayid_data_block_tag_name(enum di_displayid_data_block_tag tag) { switch (tag) { case DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID: return "Product Identification Data Block (0x00)"; case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS: return "Display Parameters Data Block (0x01)"; case DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT: return "Color Characteristics Data Block"; case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING: return "Video Timing Modes Type 1 - Detailed Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING: return "Video Timing Modes Type 2 - Detailed Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING: return "Video Timing Modes Type 3 - Short Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_TYPE_IV_TIMING: return "Video Timing Modes Type 4 - DMT Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_VESA_TIMING: return "Supported Timing Modes Type 1 - VESA DMT Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_CEA_TIMING: return "Supported Timing Modes Type 2 - CTA-861 Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_TIMING_RANGE_LIMITS: return "Video Timing Range Data Block"; case DI_DISPLAYID_DATA_BLOCK_PRODUCT_SERIAL: return "Product Serial Number Data Block"; case DI_DISPLAYID_DATA_BLOCK_ASCII_STRING: return "GP ASCII String Data Block"; case DI_DISPLAYID_DATA_BLOCK_DISPLAY_DEVICE_DATA: return "Display Device Data Data Block"; case DI_DISPLAYID_DATA_BLOCK_INTERFACE_POWER_SEQ: return "Interface Power Sequencing Data Block"; case DI_DISPLAYID_DATA_BLOCK_TRANSFER_CHARACT: return "Transfer Characteristics Data Block"; case DI_DISPLAYID_DATA_BLOCK_DISPLAY_INTERFACE: return "Display Interface Data Block"; case DI_DISPLAYID_DATA_BLOCK_STEREO_DISPLAY_INTERFACE: return "Stereo Display Interface Data Block (0x10)"; case DI_DISPLAYID_DATA_BLOCK_TYPE_V_TIMING: return "Video Timing Modes Type 5 - Short Timings Data Block"; case DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO: return "Tiled Display Topology Data Block (0x12)"; case DI_DISPLAYID_DATA_BLOCK_TYPE_VI_TIMING: return "Video Timing Modes Type 6 - Detailed Timings Data Block"; } abort(); } void print_displayid(const struct di_displayid *displayid) { const struct di_displayid_data_block *const *data_blocks; const struct di_displayid_data_block *data_block; enum di_displayid_data_block_tag tag; size_t i; const struct di_displayid_display_params *display_params; printf(" Version: %d.%d\n", di_displayid_get_version(displayid), di_displayid_get_revision(displayid)); if (is_displayid_base_block) printf(" Display Product Type: %s\n", displayid_product_type_name(di_displayid_get_product_type(displayid))); is_displayid_base_block = false; data_blocks = di_displayid_get_data_blocks(displayid); for (i = 0; data_blocks[i] != NULL; i++) { data_block = data_blocks[i]; tag = di_displayid_data_block_get_tag(data_block); printf(" %s:\n", displayid_data_block_tag_name(tag)); switch (tag) { case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS: display_params = di_displayid_data_block_get_display_params(data_block); print_displayid_display_params(display_params); break; case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING: print_displayid_type_i_timing_block(data_block); break; default: break; /* Ignore */ } } } dxvk-0~git20230309.275e645/di-edid-decode/edid.c000066400000000000000000000705251440230200600204250ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include "di-edid-decode.h" static size_t num_detailed_timing_defs = 0; static const char * standard_timing_aspect_ratio_name(enum di_edid_standard_timing_aspect_ratio aspect_ratio) { switch (aspect_ratio) { case DI_EDID_STANDARD_TIMING_16_10: return "16:10"; case DI_EDID_STANDARD_TIMING_4_3: return " 4:3 "; case DI_EDID_STANDARD_TIMING_5_4: return " 5:4 "; case DI_EDID_STANDARD_TIMING_16_9: return "16:9 "; } abort(); } static void print_standard_timing(const struct di_edid_standard_timing *t) { int32_t vert_video; const struct di_dmt_timing *dmt; int hbl, vbl, horiz_total, vert_total; double refresh, horiz_freq_hz, pixel_clock_mhz, pixel_clock_khz; struct di_gtf_options gtf_options; struct di_gtf_timing gtf; vert_video = di_edid_standard_timing_get_vert_video(t); dmt = di_edid_standard_timing_get_dmt(t); printf(" "); if (dmt) { hbl = dmt->horiz_blank - 2 * dmt->horiz_border; vbl = dmt->vert_blank - 2 * dmt->vert_border; horiz_total = dmt->horiz_video + hbl; vert_total = dmt->vert_video + vbl; refresh = (double) dmt->pixel_clock_hz / (horiz_total * vert_total); horiz_freq_hz = (double) dmt->pixel_clock_hz / horiz_total; pixel_clock_mhz = (double) dmt->pixel_clock_hz / (1000 * 1000); printf("DMT 0x%02x", dmt ? dmt->dmt_id : 0); } else { /* TODO: CVT timings */ gtf_options = (struct di_gtf_options) { .h_pixels = t->horiz_video, .v_lines = vert_video, .ip_param = DI_GTF_IP_PARAM_V_FRAME_RATE, .ip_freq_rqd = t->refresh_rate_hz, .m = DI_GTF_DEFAULT_M, .c = DI_GTF_DEFAULT_C, .k = DI_GTF_DEFAULT_K, .j = DI_GTF_DEFAULT_J, }; di_gtf_compute(>f, >f_options); hbl = gtf.h_front_porch + gtf.h_sync + gtf.h_back_porch + 2 * gtf.h_border; vbl = gtf.v_front_porch + gtf.v_sync + gtf.v_back_porch + 2 * gtf.v_border; horiz_total = gtf.h_pixels + hbl; vert_total = gtf.v_lines + vbl; /* Upstream edid-decode rounds the pixel clock to kHz... */ pixel_clock_khz = round(gtf.pixel_freq_mhz * 1000); refresh = (pixel_clock_khz * 1000) / (horiz_total * vert_total); horiz_freq_hz = (pixel_clock_khz * 1000) / horiz_total; pixel_clock_mhz = pixel_clock_khz / 1000; printf("GTF "); } printf(":"); printf(" %5dx%-5d", t->horiz_video, vert_video); printf(" %10.6f Hz", refresh); printf(" %s ", standard_timing_aspect_ratio_name(t->aspect_ratio)); printf(" %8.3f kHz %13.6f MHz", horiz_freq_hz / 1000, pixel_clock_mhz); printf("\n"); } static int gcd(int a, int b) { int tmp; while (b) { tmp = b; b = a % b; a = tmp; } return a; } static void compute_aspect_ratio(int width, int height, int *horiz_ratio, int *vert_ratio) { int d; d = gcd(width, height); if (d == 0) { *horiz_ratio = *vert_ratio = 0; } else { *horiz_ratio = width / d; *vert_ratio = height / d; } } /** * Join a list of strings into a comma-separated string. * * The list must be NULL-terminated. */ static char * join_str(const char *l[]) { char *out = NULL; size_t out_size = 0, i; FILE *f; f = open_memstream(&out, &out_size); if (!f) { return NULL; } for (i = 0; l[i] != NULL; i++) { if (i > 0) { fprintf(f, ", "); } fprintf(f, "%s", l[i]); } fclose(f); return out; } static bool has_established_timings_i_ii(const struct di_edid_established_timings_i_ii *timings) { return timings->has_720x400_70hz || timings->has_720x400_88hz || timings->has_640x480_60hz || timings->has_640x480_67hz || timings->has_640x480_72hz || timings->has_640x480_75hz || timings->has_800x600_56hz || timings->has_800x600_60hz || timings->has_800x600_72hz || timings->has_800x600_75hz || timings->has_832x624_75hz || timings->has_1024x768_87hz_interlaced || timings->has_1024x768_60hz || timings->has_1024x768_70hz || timings->has_1024x768_75hz || timings->has_1280x1024_75hz || timings->has_1152x870_75hz; } static const char * detailed_timing_def_stereo_name(enum di_edid_detailed_timing_def_stereo stereo) { switch (stereo) { case DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE: return "none"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_RIGHT: return "field sequential L/R"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_LEFT: return "field sequential R/L"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_RIGHT: return "interleaved right even"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_LEFT: return "interleaved left even"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_4_WAY_INTERLEAVED: return "four way interleaved"; case DI_EDID_DETAILED_TIMING_DEF_STEREO_SIDE_BY_SIDE_INTERLEAVED: return "side by side interleaved"; } abort(); } static const char * detailed_timing_def_signal_type_name(enum di_edid_detailed_timing_def_signal_type type) { switch (type) { case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE: return "analog composite"; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE: return "bipolar analog composite"; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE: return "digital composite"; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE: /* edid-decode doesn't print anything in this case */ return NULL; } abort(); } static bool detailed_timing_def_sync_serrations(const struct di_edid_detailed_timing_def *def) { switch (def->signal_type) { case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE: return def->analog_composite->sync_serrations; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE: return def->bipolar_analog_composite->sync_serrations; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE: return def->digital_composite->sync_serrations; default: return false; } } static bool detailed_timing_def_sync_on_green(const struct di_edid_detailed_timing_def *def) { switch (def->signal_type) { case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE: return def->analog_composite->sync_on_green; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE: return def->bipolar_analog_composite->sync_on_green; default: return false; } } static const char * detailed_timing_def_sync_polarity_name(enum di_edid_detailed_timing_def_sync_polarity polarity) { switch (polarity) { case DI_EDID_DETAILED_TIMING_DEF_SYNC_NEGATIVE: return "N"; case DI_EDID_DETAILED_TIMING_DEF_SYNC_POSITIVE: return "P"; } abort(); } void print_detailed_timing_def(const struct di_edid_detailed_timing_def *def) { int hbl, vbl, horiz_total, vert_total; int horiz_back_porch, vert_back_porch; int horiz_ratio, vert_ratio; double refresh, horiz_freq_hz; const char *flags[32] = {0}; const char *signal_type_name; char size_mm[64]; size_t flags_len = 0; enum di_edid_detailed_timing_def_sync_polarity polarity; hbl = def->horiz_blank - 2 * def->horiz_border; vbl = def->vert_blank - 2 * def->vert_border; horiz_total = def->horiz_video + hbl; vert_total = def->vert_video + vbl; refresh = (double) def->pixel_clock_hz / (horiz_total * vert_total); horiz_freq_hz = (double) def->pixel_clock_hz / horiz_total; compute_aspect_ratio(def->horiz_video, def->vert_video, &horiz_ratio, &vert_ratio); signal_type_name = detailed_timing_def_signal_type_name(def->signal_type); if (signal_type_name != NULL) { flags[flags_len++] = signal_type_name; } if (detailed_timing_def_sync_serrations(def)) { flags[flags_len++] = "serrate"; } if (detailed_timing_def_sync_on_green(def)) { flags[flags_len++] = "sync-on-green"; } if (def->stereo != DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE) { flags[flags_len++] = detailed_timing_def_stereo_name(def->stereo); } if (def->horiz_image_mm != 0 || def->vert_image_mm != 0) { snprintf(size_mm, sizeof(size_mm), "%d mm x %d mm", def->horiz_image_mm, def->vert_image_mm); flags[flags_len++] = size_mm; } assert(flags_len < sizeof(flags) / sizeof(flags[0])); printf(" DTD %zu:", ++num_detailed_timing_defs); printf(" %5dx%-5d", def->horiz_video, def->vert_video); if (def->interlaced) { printf("i"); } printf(" %10.6f Hz", refresh); printf(" %3u:%-3u", horiz_ratio, vert_ratio); printf(" %8.3f kHz %13.6f MHz", horiz_freq_hz / 1000, (double) def->pixel_clock_hz / (1000 * 1000)); if (flags_len > 0) { char *flags_str = join_str(flags); printf(" (%s)", flags_str); free(flags_str); } printf("\n"); horiz_back_porch = hbl - def->horiz_sync_pulse - def->horiz_front_porch; printf(" Hfront %4d Hsync %3d Hback %4d", def->horiz_front_porch, def->horiz_sync_pulse, horiz_back_porch); if (def->horiz_border != 0) { printf(" Hborder %d", def->horiz_border); } if (def->signal_type == DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE) { polarity = def->digital_composite->sync_horiz_polarity; printf(" Hpol %s", detailed_timing_def_sync_polarity_name(polarity)); } else if (def->signal_type == DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE) { polarity = def->digital_separate->sync_horiz_polarity; printf(" Hpol %s", detailed_timing_def_sync_polarity_name(polarity)); } printf("\n"); vert_back_porch = vbl - def->vert_sync_pulse - def->vert_front_porch; printf(" Vfront %4u Vsync %3u Vback %4d", def->vert_front_porch, def->vert_sync_pulse, vert_back_porch); if (def->vert_border != 0) { printf(" Vborder %d", def->vert_border); } if (def->signal_type == DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE) { polarity = def->digital_separate->sync_vert_polarity; printf(" Vpol %s", detailed_timing_def_sync_polarity_name(polarity)); } printf("\n"); } static const char * display_desc_tag_name(enum di_edid_display_descriptor_tag tag) { switch (tag) { case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL: return "Display Product Serial Number"; case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING: return "Alphanumeric Data String"; case DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS: return "Display Range Limits"; case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME: return "Display Product Name"; case DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT: return "Color Point Data"; case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS: return "Standard Timing Identifications"; case DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA: return "Display Color Management Data"; case DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES: return "CVT 3 Byte Timing Codes"; case DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III: return "Established timings III"; case DI_EDID_DISPLAY_DESCRIPTOR_DUMMY: return "Dummy Descriptor"; } abort(); } static const char * display_range_limits_type_name(enum di_edid_display_range_limits_type type) { switch (type) { case DI_EDID_DISPLAY_RANGE_LIMITS_BARE: return "Bare Limits"; case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF: return "GTF"; case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF: return "Secondary GTF"; case DI_EDID_DISPLAY_RANGE_LIMITS_CVT: return "CVT"; } abort(); } static const char * cvt_aspect_ratio_name(enum di_edid_cvt_aspect_ratio aspect_ratio) { switch (aspect_ratio) { case DI_EDID_CVT_ASPECT_RATIO_4_3: return "4:3"; case DI_EDID_CVT_ASPECT_RATIO_16_9: return "16:9"; case DI_EDID_CVT_ASPECT_RATIO_16_10: return "16:10"; case DI_EDID_CVT_ASPECT_RATIO_5_4: return "5:4"; case DI_EDID_CVT_ASPECT_RATIO_15_9: return "15:9"; } abort(); } static float truncate_chromaticity_coord(float coord) { return floorf(coord * 10000) / 10000; } static void print_color_point(const struct di_edid_color_point *c) { printf("Index: %u White: %.4f, %.4f ", c->index, truncate_chromaticity_coord(c->white_x), truncate_chromaticity_coord(c->white_y)); if (c->gamma != 0) { printf("Gamma: %.2f\n", c->gamma); } else { printf("Gamma: is defined in an extension block\n"); } } static void print_display_desc(const struct di_edid *edid, const struct di_edid_display_descriptor *desc) { enum di_edid_display_descriptor_tag tag; const char *tag_name, *str; const struct di_edid_display_range_limits *range_limits; enum di_edid_display_range_limits_type range_limits_type; const struct di_edid_standard_timing *const *standard_timings; const struct di_edid_color_point *const *color_points; const struct di_dmt_timing *const *established_timings_iii; const struct di_edid_color_management_data *color_management_data; size_t i; tag = di_edid_display_descriptor_get_tag(desc); tag_name = display_desc_tag_name(tag); printf(" %s:", tag_name); switch (tag) { case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL: case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING: case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME: str = di_edid_display_descriptor_get_string(desc); printf(" '%s'\n", str); break; case DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS: range_limits = di_edid_display_descriptor_get_range_limits(desc); range_limits_type = range_limits->type; if (di_edid_get_revision(edid) < 4 && range_limits_type == DI_EDID_DISPLAY_RANGE_LIMITS_BARE) { /* edid-decode always prints "GTF" for EDID 1.3 and * earlier even if the display doesn't support it */ range_limits_type = DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF; } printf("\n Monitor ranges (%s): %d-%d Hz V, %d-%d kHz H", display_range_limits_type_name(range_limits_type), range_limits->min_vert_rate_hz, range_limits->max_vert_rate_hz, range_limits->min_horiz_rate_hz / 1000, range_limits->max_horiz_rate_hz / 1000); if (range_limits->max_pixel_clock_hz != 0) { printf(", max dotclock %d MHz", range_limits->max_pixel_clock_hz / (1000 * 1000)); } printf("\n"); switch (range_limits_type) { case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF: printf(" GTF Secondary Curve Block:\n"); printf(" Start frequency: %u kHz\n", range_limits->secondary_gtf->start_freq_hz / 1000); printf(" C: %.1f%%\n", range_limits->secondary_gtf->c); printf(" M: %u%%/kHz\n", (int) range_limits->secondary_gtf->m); printf(" K: %u\n", (int) range_limits->secondary_gtf->k); printf(" J: %.1f%%\n", range_limits->secondary_gtf->j); break; case DI_EDID_DISPLAY_RANGE_LIMITS_CVT: printf(" CVT version %d.%d\n", range_limits->cvt->version, range_limits->cvt->revision); if (range_limits->cvt->max_horiz_px != 0) printf(" Max active pixels per line: %d\n", range_limits->cvt->max_horiz_px); printf(" Supported aspect ratios:"); if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_4_3) printf(" 4:3"); if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_16_9) printf(" 16:9"); if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_16_10) printf(" 16:10"); if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_5_4) printf(" 5:4"); if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_15_9) printf(" 15:9"); printf("\n"); printf(" Preferred aspect ratio: %s\n", cvt_aspect_ratio_name(range_limits->cvt->preferred_aspect_ratio)); if (range_limits->cvt->standard_blanking) printf(" Supports CVT standard blanking\n"); if (range_limits->cvt->reduced_blanking) printf(" Supports CVT reduced blanking\n"); if (range_limits->cvt->supported_scaling != 0) { printf(" Supported display scaling:\n"); if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_HORIZ_SHRINK) printf(" Horizontal shrink\n"); if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_HORIZ_STRETCH) printf(" Horizontal stretch\n"); if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_VERT_SHRINK) printf(" Vertical shrink\n"); if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_VERT_STRETCH) printf(" Vertical stretch\n"); } printf(" Preferred vertical refresh: %d Hz\n", range_limits->cvt->preferred_vert_refresh_hz); break; default: break; } break; case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS: standard_timings = di_edid_display_descriptor_get_standard_timings(desc); printf("\n"); for (i = 0; standard_timings[i] != NULL; i++) { printf(" "); print_standard_timing(standard_timings[i]); } break; case DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT: color_points = di_edid_display_descriptor_get_color_points(desc); for (i = 0; color_points[i] != NULL; i++) { printf(" "); print_color_point(color_points[i]); } uncommon_features.color_point_descriptor = true; break; case DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III: established_timings_iii = di_edid_display_descriptor_get_established_timings_iii(desc); printf("\n"); for (i = 0; established_timings_iii[i] != NULL; i++) { printf(" DMT 0x%02x\n", established_timings_iii[i]->dmt_id); } break; case DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA: color_management_data = di_edid_display_descriptor_get_color_management_data(desc); printf(" Version : %d\n", color_management_data->version); printf(" Red a3 : %.2f\n", color_management_data->red_a3); printf(" Red a2 : %.2f\n", color_management_data->red_a2); printf(" Green a3: %.2f\n", color_management_data->green_a3); printf(" Green a2: %.2f\n", color_management_data->green_a2); printf(" Blue a3 : %.2f\n", color_management_data->blue_a3); printf(" Blue a2 : %.2f\n", color_management_data->blue_a2); uncommon_features.color_management_data = true; break; default: printf("\n"); break; /* TODO: print other tags */ } } static const char * analog_signal_level_std_name(enum di_edid_video_input_analog_signal_level_std std) { switch (std) { case DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_0: return "0.700 : 0.300 : 1.000 V p-p"; case DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_1: return "0.714 : 0.286 : 1.000 V p-p"; case DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_2: return "1.000 : 0.400 : 1.400 V p-p"; case DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_3: return "0.700 : 0.000 : 0.700 V p-p"; } abort(); } static const char * digital_interface_name(enum di_edid_video_input_digital_interface interface) { switch (interface) { case DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED: return "Digital interface is not defined"; case DI_EDID_VIDEO_INPUT_DIGITAL_DVI: return "DVI interface"; case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_A: return "HDMI-a interface"; case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_B: return "HDMI-b interface"; case DI_EDID_VIDEO_INPUT_DIGITAL_MDDI: return "MDDI interface"; case DI_EDID_VIDEO_INPUT_DIGITAL_DISPLAYPORT: return "DisplayPort interface"; } abort(); } static const char * display_color_type_name(enum di_edid_display_color_type type) { switch (type) { case DI_EDID_DISPLAY_COLOR_MONOCHROME: return "Monochrome or grayscale display"; case DI_EDID_DISPLAY_COLOR_RGB: return "RGB color display"; case DI_EDID_DISPLAY_COLOR_NON_RGB: return "Non-RGB color display"; case DI_EDID_DISPLAY_COLOR_UNDEFINED: return "Undefined display color type"; } abort(); } void print_edid(const struct di_edid *edid) { const struct di_edid_vendor_product *vendor_product; const struct di_edid_video_input_analog *video_input_analog; const struct di_edid_video_input_digital *video_input_digital; const struct di_edid_screen_size *screen_size; float gamma; const struct di_edid_dpms *dpms; enum di_edid_display_color_type display_color_type; const struct di_edid_color_encoding_formats *color_encoding_formats; const struct di_edid_misc_features *misc_features; const struct di_edid_chromaticity_coords *chromaticity_coords; const struct di_edid_established_timings_i_ii *established_timings_i_ii; const struct di_edid_standard_timing *const *standard_timings; const struct di_edid_detailed_timing_def *const *detailed_timing_defs; const struct di_edid_display_descriptor *const *display_descs; size_t i; printf("Block 0, Base EDID:\n"); printf(" EDID Structure Version & Revision: %d.%d\n", di_edid_get_version(edid), di_edid_get_revision(edid)); vendor_product = di_edid_get_vendor_product(edid); printf(" Vendor & Product Identification:\n"); printf(" Manufacturer: %.3s\n", vendor_product->manufacturer); printf(" Model: %" PRIu16 "\n", vendor_product->product); if (vendor_product->serial != 0) { printf(" Serial Number: %" PRIu32 "\n", vendor_product->serial); } if (vendor_product->model_year != 0) { printf(" Model year: %d\n", vendor_product->model_year); } else { printf(" Made in: week %d of %d\n", vendor_product->manufacture_week, vendor_product->manufacture_year); } printf(" Basic Display Parameters & Features:\n"); video_input_analog = di_edid_get_video_input_analog(edid); if (video_input_analog) { printf(" Analog display\n"); printf(" Signal Level Standard: %s\n", analog_signal_level_std_name(video_input_analog->signal_level_std)); switch (video_input_analog->video_setup) { case DI_EDID_VIDEO_INPUT_ANALOG_BLANK_LEVEL_EQ_BLACK: printf(" Blank level equals black level\n"); break; case DI_EDID_VIDEO_INPUT_ANALOG_BLANK_TO_BLACK_SETUP_PEDESTAL: printf(" Blank-to-black setup/pedestal\n"); break; } printf(" Sync:"); if (video_input_analog->sync_separate) printf(" Separate"); if (video_input_analog->sync_composite) printf(" Composite"); if (video_input_analog->sync_on_green) printf(" SyncOnGreen"); if (video_input_analog->sync_serrations) printf(" Serration"); printf("\n"); } video_input_digital = di_edid_get_video_input_digital(edid); if (video_input_digital) { printf(" Digital display\n"); if (di_edid_get_revision(edid) >= 4) { if (video_input_digital->color_bit_depth == 0) { printf(" Color depth is undefined\n"); } else { printf(" Bits per primary color channel: %d\n", video_input_digital->color_bit_depth); } printf(" %s\n", digital_interface_name(video_input_digital->interface)); } if (video_input_digital->dfp1) printf(" DFP 1.x compatible TMDS\n"); } screen_size = di_edid_get_screen_size(edid); if (screen_size->width_cm > 0) { printf(" Maximum image size: %d cm x %d cm\n", screen_size->width_cm, screen_size->height_cm); } else if (screen_size->landscape_aspect_ratio > 0) { printf(" Aspect ratio: %.2f (landscape)\n", screen_size->landscape_aspect_ratio); } else if (screen_size->portait_aspect_ratio > 0) { printf(" Aspect ratio: %.2f (portrait)\n", screen_size->portait_aspect_ratio); } else { printf(" Image size is variable\n"); } gamma = di_edid_get_basic_gamma(edid); if (gamma != 0) { printf(" Gamma: %.2f\n", gamma); } else { printf(" Gamma is defined in an extension block\n"); } dpms = di_edid_get_dpms(edid); if (dpms->standby || dpms->suspend || dpms->off) { printf(" DPMS levels:"); if (dpms->standby) { printf(" Standby"); } if (dpms->suspend) { printf(" Suspend"); } if (dpms->off) { printf(" Off"); } printf("\n"); } if (!video_input_digital || di_edid_get_revision(edid) < 4) { display_color_type = di_edid_get_display_color_type(edid); printf(" %s\n", display_color_type_name(display_color_type)); } color_encoding_formats = di_edid_get_color_encoding_formats(edid); if (color_encoding_formats) { assert(color_encoding_formats->rgb444); printf(" Supported color formats: RGB 4:4:4"); if (color_encoding_formats->ycrcb444) { printf(", YCrCb 4:4:4"); } if (color_encoding_formats->ycrcb422) { printf(", YCrCb 4:2:2"); } printf("\n"); } misc_features = di_edid_get_misc_features(edid); if (misc_features->srgb_is_primary) { printf(" Default (sRGB) color space is primary color space\n"); } if (di_edid_get_revision(edid) >= 4) { assert(misc_features->has_preferred_timing); if (misc_features->preferred_timing_is_native) { printf(" First detailed timing includes the native " "pixel format and preferred refresh rate\n"); } else { printf(" First detailed timing does not include the " "native pixel format and preferred refresh rate\n"); } } else { if (misc_features->has_preferred_timing) { printf(" First detailed timing is the preferred timing\n"); } } if (misc_features->continuous_freq) { printf(" Display is continuous frequency\n"); } if (misc_features->default_gtf) { printf(" Supports GTF timings within operating range\n"); } /* edid-decode truncates the result, but %f rounds it */ chromaticity_coords = di_edid_get_chromaticity_coords(edid); printf(" Color Characteristics:\n"); printf(" Red : %.4f, %.4f\n", truncate_chromaticity_coord(chromaticity_coords->red_x), truncate_chromaticity_coord(chromaticity_coords->red_y)); printf(" Green: %.4f, %.4f\n", truncate_chromaticity_coord(chromaticity_coords->green_x), truncate_chromaticity_coord(chromaticity_coords->green_y)); printf(" Blue : %.4f, %.4f\n", truncate_chromaticity_coord(chromaticity_coords->blue_x), truncate_chromaticity_coord(chromaticity_coords->blue_y)); printf(" White: %.4f, %.4f\n", truncate_chromaticity_coord(chromaticity_coords->white_x), truncate_chromaticity_coord(chromaticity_coords->white_y)); printf(" Established Timings I & II:"); established_timings_i_ii = di_edid_get_established_timings_i_ii(edid); if (!has_established_timings_i_ii(established_timings_i_ii)) { printf(" none"); } printf("\n"); if (established_timings_i_ii->has_720x400_70hz) printf(" IBM : 720x400 70.081663 Hz 9:5 31.467 kHz 28.320000 MHz\n"); if (established_timings_i_ii->has_720x400_88hz) printf(" IBM : 720x400 87.849542 Hz 9:5 39.444 kHz 35.500000 MHz\n"); if (established_timings_i_ii->has_640x480_60hz) printf(" DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz\n"); if (established_timings_i_ii->has_640x480_67hz) printf(" Apple : 640x480 66.666667 Hz 4:3 35.000 kHz 30.240000 MHz\n"); if (established_timings_i_ii->has_640x480_72hz) printf(" DMT 0x05: 640x480 72.808802 Hz 4:3 37.861 kHz 31.500000 MHz\n"); if (established_timings_i_ii->has_640x480_75hz) printf(" DMT 0x06: 640x480 75.000000 Hz 4:3 37.500 kHz 31.500000 MHz\n"); if (established_timings_i_ii->has_800x600_56hz) printf(" DMT 0x08: 800x600 56.250000 Hz 4:3 35.156 kHz 36.000000 MHz\n"); if (established_timings_i_ii->has_800x600_60hz) printf(" DMT 0x09: 800x600 60.316541 Hz 4:3 37.879 kHz 40.000000 MHz\n"); if (established_timings_i_ii->has_800x600_72hz) printf(" DMT 0x0a: 800x600 72.187572 Hz 4:3 48.077 kHz 50.000000 MHz\n"); if (established_timings_i_ii->has_800x600_75hz) printf(" DMT 0x0b: 800x600 75.000000 Hz 4:3 46.875 kHz 49.500000 MHz\n"); if (established_timings_i_ii->has_832x624_75hz) printf(" Apple : 832x624 74.551266 Hz 4:3 49.726 kHz 57.284000 MHz\n"); if (established_timings_i_ii->has_1024x768_87hz_interlaced) printf(" DMT 0x0f: 1024x768i 86.957532 Hz 4:3 35.522 kHz 44.900000 MHz\n"); if (established_timings_i_ii->has_1024x768_60hz) printf(" DMT 0x10: 1024x768 60.003840 Hz 4:3 48.363 kHz 65.000000 MHz\n"); if (established_timings_i_ii->has_1024x768_70hz) printf(" DMT 0x11: 1024x768 70.069359 Hz 4:3 56.476 kHz 75.000000 MHz\n"); if (established_timings_i_ii->has_1024x768_75hz) printf(" DMT 0x12: 1024x768 75.028582 Hz 4:3 60.023 kHz 78.750000 MHz\n"); if (established_timings_i_ii->has_1280x1024_75hz) printf(" DMT 0x24: 1280x1024 75.024675 Hz 5:4 79.976 kHz 135.000000 MHz\n"); if (established_timings_i_ii->has_1152x870_75hz) printf(" Apple : 1152x870 75.061550 Hz 192:145 68.681 kHz 100.000000 MHz\n"); printf(" Standard Timings:"); standard_timings = di_edid_get_standard_timings(edid); if (standard_timings[0] == NULL) { printf(" none"); } printf("\n"); for (i = 0; standard_timings[i] != NULL; i++) { print_standard_timing(standard_timings[i]); } printf(" Detailed Timing Descriptors:\n"); detailed_timing_defs = di_edid_get_detailed_timing_defs(edid); for (i = 0; detailed_timing_defs[i] != NULL; i++) { print_detailed_timing_def(detailed_timing_defs[i]); } display_descs = di_edid_get_display_descriptors(edid); for (i = 0; display_descs[i] != NULL; i++) { print_display_desc(edid, display_descs[i]); } } dxvk-0~git20230309.275e645/di-edid-decode/main.c000066400000000000000000000101041440230200600204270ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include "di-edid-decode.h" struct uncommon_features uncommon_features = {0}; static const struct option long_options[] = { { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; static void usage(void) { fprintf(stderr, "Usage: di-edid-decode [in]\n" " [in]: EDID file to parse. Read from standard input (stdin),\n" " if none given.\n" "Example : di-edid-decode /sys/class/drm/card0-DP-2/edid \n" "\nOptions:\n" "-h, --help display the help message\n"); } static const char * ext_tag_name(enum di_edid_ext_tag tag) { switch (tag) { case DI_EDID_EXT_CEA: return "CTA-861 Extension Block"; case DI_EDID_EXT_VTB: return "Video Timing Extension Block"; case DI_EDID_EXT_DI: return "Display Information Extension Block"; case DI_EDID_EXT_LS: return "Localized String Extension Block"; case DI_EDID_EXT_DPVL: return "Digital Packet Video Link Extension"; case DI_EDID_EXT_BLOCK_MAP: return "Block Map Extension Block"; case DI_EDID_EXT_VENDOR: return "Manufacturer-Specific Extension Block"; case DI_EDID_EXT_DISPLAYID: return "DisplayID Extension Block"; } abort(); } static void print_ext(const struct di_edid_ext *ext, size_t ext_index) { const char *tag_name; tag_name = ext_tag_name(di_edid_ext_get_tag(ext)); printf("\n----------------\n\n"); printf("Block %zu, %s:\n", ext_index + 1, tag_name); switch (di_edid_ext_get_tag(ext)) { case DI_EDID_EXT_CEA: print_cta(di_edid_ext_get_cta(ext)); break; case DI_EDID_EXT_DISPLAYID: print_displayid(di_edid_ext_get_displayid(ext)); break; default: break; /* Ignore */ } } static size_t edid_checksum_index(size_t block_index) { return 128 * (block_index + 1) - 1; } int main(int argc, char *argv[]) { FILE *in; static uint8_t raw[32 * 1024]; size_t size = 0; const struct di_edid *edid; struct di_info *info; const struct di_edid_ext *const *exts; const char *failure_msg; size_t i; int opt; in = stdin; while (1) { int option_index = 0; opt = getopt_long(argc, argv, "h", long_options, &option_index); if (opt == -1) break; switch (opt) { case 'h': usage(); return -1; default: usage(); return -1; } } if (argc > 1) { in = fopen(argv[1], "r"); if (!in) { perror("failed to open input file"); return 1; } } while (!feof(in)) { size += fread(&raw[size], 1, sizeof(raw) - size, in); if (ferror(in)) { perror("fread failed"); return 1; } else if (size >= sizeof(raw)) { fprintf(stderr, "input too large\n"); return 1; } } fclose(in); info = di_info_parse_edid(raw, size); if (!info) { perror("di_edid_parse failed"); return 1; } edid = di_info_get_edid(info); print_edid(edid); exts = di_edid_get_extensions(edid); for (i = 0; exts[i] != NULL; i++); if (i > 0) { printf(" Extension blocks: %zu\n", i); } printf("Checksum: 0x%02hhx\n", raw[edid_checksum_index(0)]); for (i = 0; exts[i] != NULL; i++) { print_ext(exts[i], i); printf("Checksum: 0x%02hhx\n", raw[edid_checksum_index(i + 1)]); } printf("\n----------------\n\n"); failure_msg = di_info_get_failure_msg(info); if (failure_msg) { printf("Failures:\n\n%s", failure_msg); printf("EDID conformity: FAIL\n"); } else { printf("EDID conformity: PASS\n"); } if (uncommon_features.color_point_descriptor) { fprintf(stderr, "The EDID blob contains an uncommon Color " "Point Descriptor. Please share the EDID blob " "with upstream!\n"); } if (uncommon_features.color_management_data) { fprintf(stderr, "The EDID blob contains an uncommon Color " "Management Data Descriptor. Please share the " "EDID blob with upstream!\n"); } if (uncommon_features.cta_transfer_characteristics) { fprintf(stderr, "The EDID blob contains an uncommon CTA VESA " "Display Transfer Characteristic data block. " "Please share the EDID blob with upstream!\n"); } di_info_destroy(info); return failure_msg ? 254 : 0; } dxvk-0~git20230309.275e645/displayid.c000066400000000000000000000310261440230200600167530ustar00rootroot00000000000000#include #include #include #include #include "bits.h" #include "displayid.h" /** * The size of the mandatory fields in a DisplayID section. */ #define DISPLAYID_MIN_SIZE 5 /** * The maximum size of a DisplayID section. */ #define DISPLAYID_MAX_SIZE 256 /** * The size of a DisplayID data block header (tag, revision and size). */ #define DISPLAYID_DATA_BLOCK_HEADER_SIZE 3 /** * The size of a DisplayID type I timing. */ #define DISPLAYID_TYPE_I_TIMING_SIZE 20 static void add_failure(struct di_displayid *displayid, const char fmt[], ...) { va_list args; va_start(args, fmt); _di_logger_va_add_failure(displayid->logger, fmt, args); va_end(args); } static void check_data_block_revision(struct di_displayid *displayid, const uint8_t data[static_array DISPLAYID_DATA_BLOCK_HEADER_SIZE], const char *block_name, uint8_t max_revision) { uint8_t revision, flags; flags = get_bit_range(data[0x01], 7, 3); revision = get_bit_range(data[0x01], 2, 0); if (revision > max_revision) { add_failure(displayid, "%s: Unexpected revision (%u != %u).", block_name, revision, max_revision); } if (flags != 0) { add_failure(displayid, "%s: Unexpected flags (0x%02x).", block_name, flags); } } static bool parse_display_params_block(struct di_displayid *displayid, struct di_displayid_display_params_priv *priv, const uint8_t *data, size_t size) { struct di_displayid_display_params *params = &priv->base; uint8_t raw_features; check_data_block_revision(displayid, data, "Display Parameters Data Block", 0); if (size != 0x0F) { add_failure(displayid, "Display Parameters Data Block: DisplayID payload length is different than expected (%zu != %zu)", size, 0x0F); return false; } params->horiz_image_mm = 0.1f * (float)(data[0x03] | (data[0x04] << 8)); params->vert_image_mm = 0.1f * (float)(data[0x05] | (data[0x06] << 8)); params->horiz_pixels = data[0x07] | (data[0x08] << 8); params->vert_pixels = data[0x09] | (data[0x0A] << 8); raw_features = data[0x0B]; params->features = &priv->features; priv->features.audio = has_bit(raw_features, 7); priv->features.separate_audio_inputs = has_bit(raw_features, 6); priv->features.audio_input_override = has_bit(raw_features, 5); priv->features.power_management = has_bit(raw_features, 4); priv->features.fixed_timing = has_bit(raw_features, 3); priv->features.fixed_pixel_format = has_bit(raw_features, 2); priv->features.ai = has_bit(raw_features, 1); priv->features.deinterlacing = has_bit(raw_features, 0); if (data[0x0C] != 0xFF) params->gamma = (float)data[0x0C] / 100 + 1; params->aspect_ratio = (float)data[0x0D] / 100 + 1; params->bits_per_color_overall = get_bit_range(data[0x0E], 7, 4) + 1; params->bits_per_color_native = get_bit_range(data[0x0E], 3, 0) + 1; return true; } static bool parse_type_i_timing(struct di_displayid *displayid, struct di_displayid_data_block *data_block, const uint8_t data[static_array DISPLAYID_TYPE_I_TIMING_SIZE]) { int raw_pixel_clock; uint8_t stereo_3d, aspect_ratio; struct di_displayid_type_i_timing *t = calloc(1, sizeof(*t)); if (t == NULL) { return false; } raw_pixel_clock = data[0] | (data[1] << 8) | (data[2] << 16); t->pixel_clock_mhz = (double)(1 + raw_pixel_clock) * 0.01; t->preferred = has_bit(data[3], 7); t->interlaced = has_bit(data[3], 4); stereo_3d = get_bit_range(data[3], 6, 5); switch (stereo_3d) { case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_NEVER: case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_ALWAYS: case DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_USER: t->stereo_3d = stereo_3d; break; default: add_failure(displayid, "Video Timing Modes Type 1 - Detailed Timings Data Block: Reserved stereo 0x%02x.", stereo_3d); break; } aspect_ratio = get_bit_range(data[3], 3, 0); switch (aspect_ratio) { case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_1_1: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_5_4: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_4_3: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_15_9: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_9: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_10: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_64_27: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_256_135: case DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_UNDEFINED: t->aspect_ratio = aspect_ratio; break; default: t->aspect_ratio = DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_UNDEFINED; add_failure(displayid, "Video Timing Modes Type 1 - Detailed Timings Data Block: Unknown aspect 0x%02x.", aspect_ratio); break; } t->horiz_active = 1 + (data[4] | (data[5] << 8)); t->horiz_blank = 1 + (data[6] | (data[7] << 8)); t->horiz_offset = 1 + (data[8] | (get_bit_range(data[9], 6, 0) << 8)); t->horiz_sync_polarity = has_bit(data[9], 7); t->horiz_sync_width = 1 + (data[10] | (data[11] << 8)); t->vert_active = 1 + (data[12] | (data[13] << 8)); t->vert_blank = 1 + (data[14] | (data[15] << 8)); t->vert_offset = 1 + (data[16] | (get_bit_range(data[17], 6, 0) << 8)); t->vert_sync_polarity = has_bit(data[17], 7); t->vert_sync_width = 1 + (data[18] | (data[19] << 8)); assert(data_block->type_i_timings_len < DISPLAYID_MAX_TYPE_I_TIMINGS); data_block->type_i_timings[data_block->type_i_timings_len++] = t; return true; } static bool parse_type_i_timing_block(struct di_displayid *displayid, struct di_displayid_data_block *data_block, const uint8_t *data, size_t size) { size_t i; check_data_block_revision(displayid, data, "Video Timing Modes Type 1 - Detailed Timings Data Block", 1); if ((size - DISPLAYID_DATA_BLOCK_HEADER_SIZE) % DISPLAYID_TYPE_I_TIMING_SIZE != 0) { add_failure(displayid, "Video Timing Modes Type 1 - Detailed Timings Data Block: payload size not divisible by element size."); } for (i = DISPLAYID_DATA_BLOCK_HEADER_SIZE; i + DISPLAYID_TYPE_I_TIMING_SIZE <= size; i += DISPLAYID_TYPE_I_TIMING_SIZE) { if (!parse_type_i_timing(displayid, data_block, &data[i])) { return false; } } return true; } static ssize_t parse_data_block(struct di_displayid *displayid, const uint8_t *data, size_t size) { uint8_t tag; size_t data_block_size; struct di_displayid_data_block *data_block = NULL; assert(size >= DISPLAYID_DATA_BLOCK_HEADER_SIZE); tag = data[0x00]; data_block_size = (size_t) data[0x02] + DISPLAYID_DATA_BLOCK_HEADER_SIZE; if (data_block_size > size) { add_failure(displayid, "The length of this DisplayID data block (%d) exceeds the number of bytes remaining (%zu)", data_block_size, size); goto skip; } data_block = calloc(1, sizeof(*data_block)); if (!data_block) goto error; switch (tag) { case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS: if (!parse_display_params_block(displayid, &data_block->display_params, data, data_block_size)) goto error; break; case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING: if (!parse_type_i_timing_block(displayid, data_block, data, data_block_size)) goto error; break; case DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID: case DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT: case DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING: case DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING: case DI_DISPLAYID_DATA_BLOCK_TYPE_IV_TIMING: case DI_DISPLAYID_DATA_BLOCK_VESA_TIMING: case DI_DISPLAYID_DATA_BLOCK_CEA_TIMING: case DI_DISPLAYID_DATA_BLOCK_TIMING_RANGE_LIMITS: case DI_DISPLAYID_DATA_BLOCK_PRODUCT_SERIAL: case DI_DISPLAYID_DATA_BLOCK_ASCII_STRING: case DI_DISPLAYID_DATA_BLOCK_DISPLAY_DEVICE_DATA: case DI_DISPLAYID_DATA_BLOCK_INTERFACE_POWER_SEQ: case DI_DISPLAYID_DATA_BLOCK_TRANSFER_CHARACT: case DI_DISPLAYID_DATA_BLOCK_DISPLAY_INTERFACE: case DI_DISPLAYID_DATA_BLOCK_STEREO_DISPLAY_INTERFACE: case DI_DISPLAYID_DATA_BLOCK_TYPE_V_TIMING: case DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO: case DI_DISPLAYID_DATA_BLOCK_TYPE_VI_TIMING: break; /* Supported */ case 0x7F: goto skip; /* Vendor-specific */ default: add_failure(displayid, "Unknown DisplayID Data Block (0x%" PRIx8 ", length %" PRIu8 ")", tag, data_block_size - DISPLAYID_DATA_BLOCK_HEADER_SIZE); goto skip; } data_block->tag = tag; assert(displayid->data_blocks_len < DISPLAYID_MAX_DATA_BLOCKS); displayid->data_blocks[displayid->data_blocks_len++] = data_block; return (ssize_t) data_block_size; skip: free(data_block); return (ssize_t) data_block_size; error: free(data_block); return -1; } static bool is_all_zeroes(const uint8_t *data, size_t size) { size_t i; for (i = 0; i < size; i++) { if (data[i] != 0) return false; } return true; } static bool is_data_block_end(const uint8_t *data, size_t size) { if (size < DISPLAYID_DATA_BLOCK_HEADER_SIZE) return true; return is_all_zeroes(data, DISPLAYID_DATA_BLOCK_HEADER_SIZE); } static bool validate_checksum(const uint8_t *data, size_t size) { uint8_t sum = 0; size_t i; for (i = 0; i < size; i++) { sum += data[i]; } return sum == 0; } bool _di_displayid_parse(struct di_displayid *displayid, const uint8_t *data, size_t size, struct di_logger *logger) { size_t section_size, i, max_data_block_size; ssize_t data_block_size; uint8_t product_type; if (size < DISPLAYID_MIN_SIZE) { errno = EINVAL; return false; } displayid->logger = logger; displayid->version = get_bit_range(data[0x00], 7, 4); displayid->revision = get_bit_range(data[0x00], 3, 0); if (displayid->version == 0 || displayid->version > 1) { errno = ENOTSUP; return false; } section_size = (size_t) data[0x01] + DISPLAYID_MIN_SIZE; if (section_size > DISPLAYID_MAX_SIZE || section_size > size) { errno = EINVAL; return false; } if (!validate_checksum(data, section_size)) { errno = EINVAL; return false; } product_type = data[0x02]; switch (product_type) { case DI_DISPLAYID_PRODUCT_TYPE_EXTENSION: case DI_DISPLAYID_PRODUCT_TYPE_TEST: case DI_DISPLAYID_PRODUCT_TYPE_DISPLAY_PANEL: case DI_DISPLAYID_PRODUCT_TYPE_STANDALONE_DISPLAY: case DI_DISPLAYID_PRODUCT_TYPE_TV_RECEIVER: case DI_DISPLAYID_PRODUCT_TYPE_REPEATER: case DI_DISPLAYID_PRODUCT_TYPE_DIRECT_DRIVE: displayid->product_type = product_type; break; default: errno = EINVAL; return false; } i = DISPLAYID_MIN_SIZE - 1; max_data_block_size = 0; while (i < section_size - 1) { max_data_block_size = section_size - 1 - i; if (is_data_block_end(&data[i], max_data_block_size)) break; data_block_size = parse_data_block(displayid, &data[i], max_data_block_size); if (data_block_size < 0) return false; assert(data_block_size > 0); i += (size_t) data_block_size; } if (!is_all_zeroes(&data[i], max_data_block_size)) { if (max_data_block_size < DISPLAYID_DATA_BLOCK_HEADER_SIZE) add_failure(displayid, "Not enough bytes remain (%zu) for a DisplayID data block and the DisplayID filler is non-0.", max_data_block_size); else add_failure(displayid, "Padding: Contains non-zero bytes."); } displayid->logger = NULL; return true; } static void destroy_data_block(struct di_displayid_data_block *data_block) { size_t i; switch (data_block->tag) { case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING: for (i = 0; i < data_block->type_i_timings_len; i++) free(data_block->type_i_timings[i]); break; default: break; /* Nothing to do */ } free(data_block); } void _di_displayid_finish(struct di_displayid *displayid) { size_t i; for (i = 0; i < displayid->data_blocks_len; i++) destroy_data_block(displayid->data_blocks[i]); } int di_displayid_get_version(const struct di_displayid *displayid) { return displayid->version; } int di_displayid_get_revision(const struct di_displayid *displayid) { return displayid->revision; } enum di_displayid_product_type di_displayid_get_product_type(const struct di_displayid *displayid) { return displayid->product_type; } enum di_displayid_data_block_tag di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block) { return data_block->tag; } const struct di_displayid_display_params * di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block) { if (data_block->tag != DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS) { return NULL; } return &data_block->display_params.base; } const struct di_displayid_type_i_timing *const * di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *data_block) { if (data_block->tag != DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING) { return NULL; } return (const struct di_displayid_type_i_timing *const *) data_block->type_i_timings; } const struct di_displayid_data_block *const * di_displayid_get_data_blocks(const struct di_displayid *displayid) { return (const struct di_displayid_data_block *const *) displayid->data_blocks; } dxvk-0~git20230309.275e645/dmt-table.c000066400000000000000000000735351440230200600166550ustar00rootroot00000000000000/* DO NOT EDIT! This file has been generated by gen-dmt.py from DMT-r1-v13.pdf. */ #include "dmt.h" const struct di_dmt_timing _di_dmt_timings[] = { { .dmt_id = 0x01, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 640, .vert_video = 350, .refresh_rate_hz = 85.0, .pixel_clock_hz = 31500000, .horiz_blank = 192, .horiz_front_porch = 32, .horiz_sync_pulse = 64, .horiz_border = 0, .vert_blank = 95, .vert_front_porch = 32, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x02, .edid_std_id = 0x3119, .cvt_id = 0, .horiz_video = 640, .vert_video = 400, .refresh_rate_hz = 85.0, .pixel_clock_hz = 31500000, .horiz_blank = 192, .horiz_front_porch = 32, .horiz_sync_pulse = 64, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x03, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 720, .vert_video = 400, .refresh_rate_hz = 85.0, .pixel_clock_hz = 35500000, .horiz_blank = 216, .horiz_front_porch = 36, .horiz_sync_pulse = 72, .horiz_border = 0, .vert_blank = 46, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x04, .edid_std_id = 0x3140, .cvt_id = 0, .horiz_video = 640, .vert_video = 480, .refresh_rate_hz = 60.0, .pixel_clock_hz = 25175000, .horiz_blank = 144, .horiz_front_porch = 8, .horiz_sync_pulse = 96, .horiz_border = 8, .vert_blank = 29, .vert_front_porch = 2, .vert_sync_pulse = 2, .vert_border = 8, }, { .dmt_id = 0x05, .edid_std_id = 0x314C, .cvt_id = 0, .horiz_video = 640, .vert_video = 480, .refresh_rate_hz = 72.0, .pixel_clock_hz = 31500000, .horiz_blank = 176, .horiz_front_porch = 16, .horiz_sync_pulse = 40, .horiz_border = 8, .vert_blank = 24, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 8, }, { .dmt_id = 0x06, .edid_std_id = 0x314F, .cvt_id = 0, .horiz_video = 640, .vert_video = 480, .refresh_rate_hz = 75.0, .pixel_clock_hz = 31500000, .horiz_blank = 200, .horiz_front_porch = 16, .horiz_sync_pulse = 64, .horiz_border = 0, .vert_blank = 20, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x07, .edid_std_id = 0x3159, .cvt_id = 0, .horiz_video = 640, .vert_video = 480, .refresh_rate_hz = 85.0, .pixel_clock_hz = 36000000, .horiz_blank = 192, .horiz_front_porch = 56, .horiz_sync_pulse = 56, .horiz_border = 0, .vert_blank = 29, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x08, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 56.0, .pixel_clock_hz = 36000000, .horiz_blank = 224, .horiz_front_porch = 24, .horiz_sync_pulse = 72, .horiz_border = 0, .vert_blank = 25, .vert_front_porch = 1, .vert_sync_pulse = 2, .vert_border = 0, }, { .dmt_id = 0x09, .edid_std_id = 0x4540, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 60.0, .pixel_clock_hz = 40000000, .horiz_blank = 256, .horiz_front_porch = 40, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 28, .vert_front_porch = 1, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x0A, .edid_std_id = 0x454C, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 72.0, .pixel_clock_hz = 50000000, .horiz_blank = 240, .horiz_front_porch = 56, .horiz_sync_pulse = 120, .horiz_border = 0, .vert_blank = 66, .vert_front_porch = 37, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x0B, .edid_std_id = 0x454F, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 75.0, .pixel_clock_hz = 49500000, .horiz_blank = 256, .horiz_front_porch = 16, .horiz_sync_pulse = 80, .horiz_border = 0, .vert_blank = 25, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x0C, .edid_std_id = 0x4559, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 85.0, .pixel_clock_hz = 56250000, .horiz_blank = 248, .horiz_front_porch = 32, .horiz_sync_pulse = 64, .horiz_border = 0, .vert_blank = 31, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x0D, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 800, .vert_video = 600, .refresh_rate_hz = 120.0, .pixel_clock_hz = 73250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 36, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x0E, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 848, .vert_video = 480, .refresh_rate_hz = 60.0, .pixel_clock_hz = 33750000, .horiz_blank = 240, .horiz_front_porch = 16, .horiz_sync_pulse = 112, .horiz_border = 0, .vert_blank = 37, .vert_front_porch = 6, .vert_sync_pulse = 8, .vert_border = 0, }, { .dmt_id = 0x0F, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 43.0, .pixel_clock_hz = 44900000, .horiz_blank = 240, .horiz_front_porch = 8, .horiz_sync_pulse = 176, .horiz_border = 0, .vert_blank = 24, .vert_front_porch = 0, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x10, .edid_std_id = 0x6140, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 65000000, .horiz_blank = 320, .horiz_front_porch = 24, .horiz_sync_pulse = 136, .horiz_border = 0, .vert_blank = 38, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x11, .edid_std_id = 0x614A, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 70.0, .pixel_clock_hz = 75000000, .horiz_blank = 304, .horiz_front_porch = 24, .horiz_sync_pulse = 136, .horiz_border = 0, .vert_blank = 38, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x12, .edid_std_id = 0x614F, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 75.0, .pixel_clock_hz = 78750000, .horiz_blank = 288, .horiz_front_porch = 16, .horiz_sync_pulse = 96, .horiz_border = 0, .vert_blank = 32, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x13, .edid_std_id = 0x6159, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 85.0, .pixel_clock_hz = 94500000, .horiz_blank = 352, .horiz_front_porch = 48, .horiz_sync_pulse = 96, .horiz_border = 0, .vert_blank = 40, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x14, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1024, .vert_video = 768, .refresh_rate_hz = 120.0, .pixel_clock_hz = 115500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x15, .edid_std_id = 0x714F, .cvt_id = 0, .horiz_video = 1152, .vert_video = 864, .refresh_rate_hz = 75.0, .pixel_clock_hz = 108000000, .horiz_blank = 448, .horiz_front_porch = 64, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 36, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x55, .edid_std_id = 0x81C0, .cvt_id = 0, .horiz_video = 1280, .vert_video = 720, .refresh_rate_hz = 60.0, .pixel_clock_hz = 74250000, .horiz_blank = 370, .horiz_front_porch = 110, .horiz_sync_pulse = 40, .horiz_border = 0, .vert_blank = 30, .vert_front_porch = 5, .vert_sync_pulse = 5, .vert_border = 0, }, { .dmt_id = 0x16, .edid_std_id = 0, .cvt_id = 0x7F1C21, .horiz_video = 1280, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 68250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 22, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x17, .edid_std_id = 0, .cvt_id = 0x7F1C28, .horiz_video = 1280, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 79500000, .horiz_blank = 384, .horiz_front_porch = 64, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 30, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x18, .edid_std_id = 0, .cvt_id = 0x7F1C44, .horiz_video = 1280, .vert_video = 768, .refresh_rate_hz = 75.0, .pixel_clock_hz = 102250000, .horiz_blank = 416, .horiz_front_porch = 80, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 37, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x19, .edid_std_id = 0, .cvt_id = 0x7F1C62, .horiz_video = 1280, .vert_video = 768, .refresh_rate_hz = 85.0, .pixel_clock_hz = 117500000, .horiz_blank = 432, .horiz_front_porch = 80, .horiz_sync_pulse = 136, .horiz_border = 0, .vert_blank = 41, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x1A, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1280, .vert_video = 768, .refresh_rate_hz = 120.0, .pixel_clock_hz = 140250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x1B, .edid_std_id = 0, .cvt_id = 0x8F1821, .horiz_video = 1280, .vert_video = 800, .refresh_rate_hz = 60.0, .pixel_clock_hz = 71000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 23, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x1C, .edid_std_id = 0x8100, .cvt_id = 0x8F1828, .horiz_video = 1280, .vert_video = 800, .refresh_rate_hz = 60.0, .pixel_clock_hz = 83500000, .horiz_blank = 400, .horiz_front_porch = 72, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 31, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x1D, .edid_std_id = 0x810F, .cvt_id = 0x8F1844, .horiz_video = 1280, .vert_video = 800, .refresh_rate_hz = 75.0, .pixel_clock_hz = 106500000, .horiz_blank = 416, .horiz_front_porch = 80, .horiz_sync_pulse = 128, .horiz_border = 0, .vert_blank = 38, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x1E, .edid_std_id = 0x8119, .cvt_id = 0x8F1862, .horiz_video = 1280, .vert_video = 800, .refresh_rate_hz = 85.0, .pixel_clock_hz = 122500000, .horiz_blank = 432, .horiz_front_porch = 80, .horiz_sync_pulse = 136, .horiz_border = 0, .vert_blank = 43, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x1F, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1280, .vert_video = 800, .refresh_rate_hz = 120.0, .pixel_clock_hz = 146250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 47, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x20, .edid_std_id = 0x8140, .cvt_id = 0, .horiz_video = 1280, .vert_video = 960, .refresh_rate_hz = 60.0, .pixel_clock_hz = 108000000, .horiz_blank = 520, .horiz_front_porch = 96, .horiz_sync_pulse = 112, .horiz_border = 0, .vert_blank = 40, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x21, .edid_std_id = 0x8159, .cvt_id = 0, .horiz_video = 1280, .vert_video = 960, .refresh_rate_hz = 85.0, .pixel_clock_hz = 148500000, .horiz_blank = 448, .horiz_front_porch = 64, .horiz_sync_pulse = 160, .horiz_border = 0, .vert_blank = 51, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x22, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1280, .vert_video = 960, .refresh_rate_hz = 120.0, .pixel_clock_hz = 175500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 57, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x23, .edid_std_id = 0x8180, .cvt_id = 0, .horiz_video = 1280, .vert_video = 1024, .refresh_rate_hz = 60.0, .pixel_clock_hz = 108000000, .horiz_blank = 408, .horiz_front_porch = 48, .horiz_sync_pulse = 112, .horiz_border = 0, .vert_blank = 42, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x24, .edid_std_id = 0x818F, .cvt_id = 0, .horiz_video = 1280, .vert_video = 1024, .refresh_rate_hz = 75.0, .pixel_clock_hz = 135000000, .horiz_blank = 408, .horiz_front_porch = 16, .horiz_sync_pulse = 144, .horiz_border = 0, .vert_blank = 42, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x25, .edid_std_id = 0x8199, .cvt_id = 0, .horiz_video = 1280, .vert_video = 1024, .refresh_rate_hz = 85.0, .pixel_clock_hz = 157500000, .horiz_blank = 448, .horiz_front_porch = 64, .horiz_sync_pulse = 160, .horiz_border = 0, .vert_blank = 48, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x26, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1280, .vert_video = 1024, .refresh_rate_hz = 120.0, .pixel_clock_hz = 187250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 60, .vert_front_porch = 3, .vert_sync_pulse = 7, .vert_border = 0, }, { .dmt_id = 0x27, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1360, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 85500000, .horiz_blank = 432, .horiz_front_porch = 64, .horiz_sync_pulse = 112, .horiz_border = 0, .vert_blank = 27, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x28, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1360, .vert_video = 768, .refresh_rate_hz = 120.0, .pixel_clock_hz = 148250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 3, .vert_sync_pulse = 5, .vert_border = 0, }, { .dmt_id = 0x51, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1366, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 85500000, .horiz_blank = 426, .horiz_front_porch = 70, .horiz_sync_pulse = 143, .horiz_border = 0, .vert_blank = 30, .vert_front_porch = 3, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x56, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1366, .vert_video = 768, .refresh_rate_hz = 60.0, .pixel_clock_hz = 72000000, .horiz_blank = 134, .horiz_front_porch = 14, .horiz_sync_pulse = 56, .horiz_border = 0, .vert_blank = 32, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x29, .edid_std_id = 0, .cvt_id = 0x0C2021, .horiz_video = 1400, .vert_video = 1050, .refresh_rate_hz = 60.0, .pixel_clock_hz = 101000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 30, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x2A, .edid_std_id = 0x9040, .cvt_id = 0x0C2028, .horiz_video = 1400, .vert_video = 1050, .refresh_rate_hz = 60.0, .pixel_clock_hz = 121750000, .horiz_blank = 464, .horiz_front_porch = 88, .horiz_sync_pulse = 144, .horiz_border = 0, .vert_blank = 39, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x2B, .edid_std_id = 0x904F, .cvt_id = 0x0C2044, .horiz_video = 1400, .vert_video = 1050, .refresh_rate_hz = 75.0, .pixel_clock_hz = 156000000, .horiz_blank = 496, .horiz_front_porch = 104, .horiz_sync_pulse = 144, .horiz_border = 0, .vert_blank = 49, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x2C, .edid_std_id = 0x9059, .cvt_id = 0x0C2062, .horiz_video = 1400, .vert_video = 1050, .refresh_rate_hz = 85.0, .pixel_clock_hz = 179500000, .horiz_blank = 512, .horiz_front_porch = 104, .horiz_sync_pulse = 152, .horiz_border = 0, .vert_blank = 55, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x2D, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1400, .vert_video = 1050, .refresh_rate_hz = 120.0, .pixel_clock_hz = 208000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 62, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x2E, .edid_std_id = 0, .cvt_id = 0xC11821, .horiz_video = 1440, .vert_video = 900, .refresh_rate_hz = 60.0, .pixel_clock_hz = 88750000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 26, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x2F, .edid_std_id = 0x9500, .cvt_id = 0xC11828, .horiz_video = 1440, .vert_video = 900, .refresh_rate_hz = 60.0, .pixel_clock_hz = 106500000, .horiz_blank = 464, .horiz_front_porch = 80, .horiz_sync_pulse = 152, .horiz_border = 0, .vert_blank = 34, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x30, .edid_std_id = 0x950F, .cvt_id = 0xC11844, .horiz_video = 1440, .vert_video = 900, .refresh_rate_hz = 75.0, .pixel_clock_hz = 136750000, .horiz_blank = 496, .horiz_front_porch = 96, .horiz_sync_pulse = 152, .horiz_border = 0, .vert_blank = 42, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x31, .edid_std_id = 0x9519, .cvt_id = 0xC11868, .horiz_video = 1440, .vert_video = 900, .refresh_rate_hz = 85.0, .pixel_clock_hz = 157000000, .horiz_blank = 512, .horiz_front_porch = 104, .horiz_sync_pulse = 152, .horiz_border = 0, .vert_blank = 48, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x32, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1440, .vert_video = 900, .refresh_rate_hz = 120.0, .pixel_clock_hz = 182750000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 53, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x53, .edid_std_id = 0xA9C0, .cvt_id = 0, .horiz_video = 1600, .vert_video = 900, .refresh_rate_hz = 60.0, .pixel_clock_hz = 108000000, .horiz_blank = 200, .horiz_front_porch = 24, .horiz_sync_pulse = 80, .horiz_border = 0, .vert_blank = 100, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x33, .edid_std_id = 0xA940, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 60.0, .pixel_clock_hz = 162000000, .horiz_blank = 560, .horiz_front_porch = 64, .horiz_sync_pulse = 192, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x34, .edid_std_id = 0xA945, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 65.0, .pixel_clock_hz = 175500000, .horiz_blank = 560, .horiz_front_porch = 64, .horiz_sync_pulse = 192, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x35, .edid_std_id = 0xA94A, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 70.0, .pixel_clock_hz = 189000000, .horiz_blank = 560, .horiz_front_porch = 64, .horiz_sync_pulse = 192, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x36, .edid_std_id = 0xA94F, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 75.0, .pixel_clock_hz = 202500000, .horiz_blank = 560, .horiz_front_porch = 64, .horiz_sync_pulse = 192, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x37, .edid_std_id = 0xA959, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 85.0, .pixel_clock_hz = 229500000, .horiz_blank = 560, .horiz_front_porch = 64, .horiz_sync_pulse = 192, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x38, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1600, .vert_video = 1200, .refresh_rate_hz = 120.0, .pixel_clock_hz = 268250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 71, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x39, .edid_std_id = 0, .cvt_id = 0x0C2821, .horiz_video = 1680, .vert_video = 1050, .refresh_rate_hz = 60.0, .pixel_clock_hz = 119000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 30, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x3A, .edid_std_id = 0xB300, .cvt_id = 0x0C2828, .horiz_video = 1680, .vert_video = 1050, .refresh_rate_hz = 60.0, .pixel_clock_hz = 146250000, .horiz_blank = 560, .horiz_front_porch = 104, .horiz_sync_pulse = 176, .horiz_border = 0, .vert_blank = 39, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x3B, .edid_std_id = 0xB30F, .cvt_id = 0x0C2844, .horiz_video = 1680, .vert_video = 1050, .refresh_rate_hz = 75.0, .pixel_clock_hz = 187000000, .horiz_blank = 592, .horiz_front_porch = 120, .horiz_sync_pulse = 176, .horiz_border = 0, .vert_blank = 49, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x3C, .edid_std_id = 0xB319, .cvt_id = 0x0C2868, .horiz_video = 1680, .vert_video = 1050, .refresh_rate_hz = 85.0, .pixel_clock_hz = 214750000, .horiz_blank = 608, .horiz_front_porch = 128, .horiz_sync_pulse = 176, .horiz_border = 0, .vert_blank = 55, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x3D, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1680, .vert_video = 1050, .refresh_rate_hz = 120.0, .pixel_clock_hz = 245500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 62, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x3E, .edid_std_id = 0xC140, .cvt_id = 0, .horiz_video = 1792, .vert_video = 1344, .refresh_rate_hz = 60.0, .pixel_clock_hz = 204750000, .horiz_blank = 656, .horiz_front_porch = 128, .horiz_sync_pulse = 200, .horiz_border = 0, .vert_blank = 50, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x3F, .edid_std_id = 0xC14F, .cvt_id = 0, .horiz_video = 1792, .vert_video = 1344, .refresh_rate_hz = 75.0, .pixel_clock_hz = 261000000, .horiz_blank = 664, .horiz_front_porch = 96, .horiz_sync_pulse = 216, .horiz_border = 0, .vert_blank = 73, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x40, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1792, .vert_video = 1344, .refresh_rate_hz = 120.0, .pixel_clock_hz = 333250000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 79, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x41, .edid_std_id = 0xC940, .cvt_id = 0, .horiz_video = 1856, .vert_video = 1392, .refresh_rate_hz = 60.0, .pixel_clock_hz = 218250000, .horiz_blank = 672, .horiz_front_porch = 96, .horiz_sync_pulse = 224, .horiz_border = 0, .vert_blank = 47, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x42, .edid_std_id = 0xC94F, .cvt_id = 0, .horiz_video = 1856, .vert_video = 1392, .refresh_rate_hz = 75.0, .pixel_clock_hz = 288000000, .horiz_blank = 704, .horiz_front_porch = 128, .horiz_sync_pulse = 224, .horiz_border = 0, .vert_blank = 108, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x43, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1856, .vert_video = 1392, .refresh_rate_hz = 120.0, .pixel_clock_hz = 356500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 82, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x52, .edid_std_id = 0xD1C0, .cvt_id = 0, .horiz_video = 1920, .vert_video = 1080, .refresh_rate_hz = 60.0, .pixel_clock_hz = 148500000, .horiz_blank = 280, .horiz_front_porch = 88, .horiz_sync_pulse = 44, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 4, .vert_sync_pulse = 5, .vert_border = 0, }, { .dmt_id = 0x44, .edid_std_id = 0, .cvt_id = 0x572821, .horiz_video = 1920, .vert_video = 1200, .refresh_rate_hz = 60.0, .pixel_clock_hz = 154000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 35, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x45, .edid_std_id = 0xD100, .cvt_id = 0x572828, .horiz_video = 1920, .vert_video = 1200, .refresh_rate_hz = 60.0, .pixel_clock_hz = 193250000, .horiz_blank = 672, .horiz_front_porch = 136, .horiz_sync_pulse = 200, .horiz_border = 0, .vert_blank = 45, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x46, .edid_std_id = 0xD10F, .cvt_id = 0x572844, .horiz_video = 1920, .vert_video = 1200, .refresh_rate_hz = 75.0, .pixel_clock_hz = 245250000, .horiz_blank = 688, .horiz_front_porch = 136, .horiz_sync_pulse = 208, .horiz_border = 0, .vert_blank = 55, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x47, .edid_std_id = 0xD119, .cvt_id = 0x572862, .horiz_video = 1920, .vert_video = 1200, .refresh_rate_hz = 85.0, .pixel_clock_hz = 281250000, .horiz_blank = 704, .horiz_front_porch = 144, .horiz_sync_pulse = 208, .horiz_border = 0, .vert_blank = 62, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x48, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1920, .vert_video = 1200, .refresh_rate_hz = 120.0, .pixel_clock_hz = 317000000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 71, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x49, .edid_std_id = 0xD140, .cvt_id = 0, .horiz_video = 1920, .vert_video = 1440, .refresh_rate_hz = 60.0, .pixel_clock_hz = 234000000, .horiz_blank = 680, .horiz_front_porch = 128, .horiz_sync_pulse = 208, .horiz_border = 0, .vert_blank = 60, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x4A, .edid_std_id = 0xD14F, .cvt_id = 0, .horiz_video = 1920, .vert_video = 1440, .refresh_rate_hz = 75.0, .pixel_clock_hz = 297000000, .horiz_blank = 720, .horiz_front_porch = 144, .horiz_sync_pulse = 224, .horiz_border = 0, .vert_blank = 60, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x4B, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 1920, .vert_video = 1440, .refresh_rate_hz = 120.0, .pixel_clock_hz = 380500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 85, .vert_front_porch = 3, .vert_sync_pulse = 4, .vert_border = 0, }, { .dmt_id = 0x54, .edid_std_id = 0xE1C0, .cvt_id = 0, .horiz_video = 2048, .vert_video = 1152, .refresh_rate_hz = 60.0, .pixel_clock_hz = 162000000, .horiz_blank = 202, .horiz_front_porch = 26, .horiz_sync_pulse = 80, .horiz_border = 0, .vert_blank = 48, .vert_front_porch = 1, .vert_sync_pulse = 3, .vert_border = 0, }, { .dmt_id = 0x4C, .edid_std_id = 0, .cvt_id = 0x1F3821, .horiz_video = 2560, .vert_video = 1600, .refresh_rate_hz = 60.0, .pixel_clock_hz = 268500000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 46, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x4D, .edid_std_id = 0, .cvt_id = 0x1F3828, .horiz_video = 2560, .vert_video = 1600, .refresh_rate_hz = 60.0, .pixel_clock_hz = 348500000, .horiz_blank = 944, .horiz_front_porch = 192, .horiz_sync_pulse = 280, .horiz_border = 0, .vert_blank = 58, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x4E, .edid_std_id = 0, .cvt_id = 0x1F3844, .horiz_video = 2560, .vert_video = 1600, .refresh_rate_hz = 75.0, .pixel_clock_hz = 443250000, .horiz_blank = 976, .horiz_front_porch = 208, .horiz_sync_pulse = 280, .horiz_border = 0, .vert_blank = 72, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x4F, .edid_std_id = 0, .cvt_id = 0x1F3862, .horiz_video = 2560, .vert_video = 1600, .refresh_rate_hz = 85.0, .pixel_clock_hz = 505250000, .horiz_blank = 976, .horiz_front_porch = 208, .horiz_sync_pulse = 280, .horiz_border = 0, .vert_blank = 82, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, { .dmt_id = 0x50, .edid_std_id = 0, .cvt_id = 0, .horiz_video = 2560, .vert_video = 1600, .refresh_rate_hz = 120.0, .pixel_clock_hz = 552750000, .horiz_blank = 160, .horiz_front_porch = 48, .horiz_sync_pulse = 32, .horiz_border = 0, .vert_blank = 94, .vert_front_porch = 3, .vert_sync_pulse = 6, .vert_border = 0, }, }; const size_t _di_dmt_timings_len = 86; dxvk-0~git20230309.275e645/edid.c000066400000000000000000001177121440230200600157050ustar00rootroot00000000000000#include #include #include #include #include #include "bits.h" #include "dmt.h" #include "edid.h" #include "log.h" /** * The size of an EDID block, defined in section 2.2. */ #define EDID_BLOCK_SIZE 128 /** * The size of an EDID standard timing, defined in section 3.9. */ #define EDID_STANDARD_TIMING_SIZE 2 /** * Fixed EDID header, defined in section 3.1. */ static const uint8_t header[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }; static void add_failure(struct di_edid *edid, const char fmt[], ...) { va_list args; va_start(args, fmt); _di_logger_va_add_failure(edid->logger, fmt, args); va_end(args); } static void add_failure_until(struct di_edid *edid, int revision, const char fmt[], ...) { va_list args; if (edid->revision > revision) { return; } va_start(args, fmt); _di_logger_va_add_failure(edid->logger, fmt, args); va_end(args); } static void parse_version_revision(const uint8_t data[static_array EDID_BLOCK_SIZE], int *version, int *revision) { *version = (int) data[0x12]; *revision = (int) data[0x13]; } static size_t parse_ext_count(const uint8_t data[static_array EDID_BLOCK_SIZE]) { return data[0x7E]; } static bool validate_block_checksum(const uint8_t data[static_array EDID_BLOCK_SIZE]) { uint8_t sum = 0; size_t i; for (i = 0; i < EDID_BLOCK_SIZE; i++) { sum += data[i]; } return sum == 0; } static void parse_vendor_product(struct di_edid *edid, const uint8_t data[static_array EDID_BLOCK_SIZE]) { struct di_edid_vendor_product *out = &edid->vendor_product; uint16_t man, raw_week, raw_year; int year = 0; /* The ASCII 3-letter manufacturer code is encoded in 5-bit codes. */ man = (uint16_t) ((data[0x08] << 8) | data[0x09]); out->manufacturer[0] = ((man >> 10) & 0x1F) + '@'; out->manufacturer[1] = ((man >> 5) & 0x1F) + '@'; out->manufacturer[2] = ((man >> 0) & 0x1F) + '@'; out->product = (uint16_t) (data[0x0A] | (data[0x0B] << 8)); out->serial = (uint32_t) (data[0x0C] | (data[0x0D] << 8) | (data[0x0E] << 16) | (data[0x0F] << 24)); raw_week = data[0x10]; raw_year = data[0x11]; if (raw_year >= 0x10 || edid->revision < 4) { year = data[0x11] + 1990; } else if (edid->revision == 4) { add_failure(edid, "Year set to reserved value."); } if (raw_week == 0xFF) { /* Special flag for model year */ out->model_year = year; } else { out->manufacture_year = year; if (raw_week > 54) { add_failure_until(edid, 4, "Invalid week %u of manufacture.", raw_week); } else if (raw_week > 0) { out->manufacture_week = raw_week; } } } static void parse_video_input_digital(struct di_edid *edid, uint8_t video_input) { uint8_t color_bit_depth, interface; struct di_edid_video_input_digital *digital = &edid->video_input_digital; if (edid->revision < 2) { if (get_bit_range(video_input, 6, 0) != 0) add_failure(edid, "Digital Video Interface Standard set to reserved value 0x%02x.", video_input); return; } if (edid->revision < 4) { if (get_bit_range(video_input, 6, 1) != 0) add_failure(edid, "Digital Video Interface Standard set to reserved value 0x%02x.", video_input); digital->dfp1 = has_bit(video_input, 0); return; } color_bit_depth = get_bit_range(video_input, 6, 4); if (color_bit_depth == 0x07) { /* Reserved */ add_failure_until(edid, 4, "Color Bit Depth set to reserved value."); } else if (color_bit_depth != 0) { digital->color_bit_depth = 2 * color_bit_depth + 4; } interface = get_bit_range(video_input, 3, 0); switch (interface) { case DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED: case DI_EDID_VIDEO_INPUT_DIGITAL_DVI: case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_A: case DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_B: case DI_EDID_VIDEO_INPUT_DIGITAL_MDDI: case DI_EDID_VIDEO_INPUT_DIGITAL_DISPLAYPORT: digital->interface = interface; break; default: add_failure_until(edid, 4, "Digital Video Interface Standard set to reserved value 0x%02x.", interface); digital->interface = DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED; break; } } static void parse_video_input_analog(struct di_edid *edid, uint8_t video_input) { struct di_edid_video_input_analog *analog = &edid->video_input_analog; analog->signal_level_std = get_bit_range(video_input, 6, 5); analog->video_setup = has_bit(video_input, 4); analog->sync_separate = has_bit(video_input, 3); analog->sync_composite = has_bit(video_input, 2); analog->sync_on_green = has_bit(video_input, 1); analog->sync_serrations = has_bit(video_input, 0); } static void parse_basic_params_features(struct di_edid *edid, const uint8_t data[static_array EDID_BLOCK_SIZE]) { uint8_t video_input, width, height, features; struct di_edid_screen_size *screen_size = &edid->screen_size; video_input = data[0x14]; edid->is_digital = has_bit(video_input, 7); if (edid->is_digital) { parse_video_input_digital(edid, video_input); } else { parse_video_input_analog(edid, video_input); } /* v1.3 says screen size is undefined if either byte is zero, v1.4 says * screen size and aspect ratio are undefined if both bytes are zero and * encodes the aspect ratio if either byte is zero. */ width = data[0x15]; height = data[0x16]; if (width > 0 && height > 0) { screen_size->width_cm = width; screen_size->height_cm = height; } else if (edid->revision >= 4) { if (width > 0) { screen_size->landscape_aspect_ratio = ((float) width + 99) / 100; } else if (height > 0) { screen_size->portait_aspect_ratio = ((float) height + 99) / 100; } } if (data[0x17] != 0xFF) { edid->gamma = ((float) data[0x17] + 100) / 100; } else { edid->gamma = 0; } features = data[0x18]; edid->dpms.standby = has_bit(features, 7); edid->dpms.suspend = has_bit(features, 6); edid->dpms.off = has_bit(features, 5); if (edid->is_digital && edid->revision >= 4) { edid->color_encoding_formats.rgb444 = true; edid->color_encoding_formats.ycrcb444 = has_bit(features, 3); edid->color_encoding_formats.ycrcb422 = has_bit(features, 4); edid->display_color_type = DI_EDID_DISPLAY_COLOR_UNDEFINED; } else { edid->display_color_type = get_bit_range(features, 4, 3); } if (edid->revision >= 4) { edid->misc_features.has_preferred_timing = true; edid->misc_features.continuous_freq = has_bit(features, 0); edid->misc_features.preferred_timing_is_native = has_bit(features, 1); } else { edid->misc_features.default_gtf = has_bit(features, 0); edid->misc_features.has_preferred_timing = has_bit(features, 1); } edid->misc_features.srgb_is_primary = has_bit(features, 2); } static float decode_chromaticity_coord(uint8_t hi, uint8_t lo) { uint16_t raw; /* only 10 bits are used */ raw = (uint16_t) ((hi << 2) | lo); return (float) raw / 1024; } static void parse_chromaticity_coords(struct di_edid *edid, const uint8_t data[static_array EDID_BLOCK_SIZE]) { uint8_t lo; bool all_set, any_set; struct di_edid_chromaticity_coords *coords; coords = &edid->chromaticity_coords; lo = data[0x19]; coords->red_x = decode_chromaticity_coord(data[0x1B], get_bit_range(lo, 7, 6)); coords->red_y = decode_chromaticity_coord(data[0x1C], get_bit_range(lo, 5, 4)); coords->green_x = decode_chromaticity_coord(data[0x1D], get_bit_range(lo, 3, 2)); coords->green_y = decode_chromaticity_coord(data[0x1E], get_bit_range(lo, 1, 0)); lo = data[0x1A]; coords->blue_x = decode_chromaticity_coord(data[0x1F], get_bit_range(lo, 7, 6)); coords->blue_y = decode_chromaticity_coord(data[0x20], get_bit_range(lo, 5, 4)); coords->white_x = decode_chromaticity_coord(data[0x21], get_bit_range(lo, 3, 2)); coords->white_y = decode_chromaticity_coord(data[0x22], get_bit_range(lo, 1, 0)); /* Either all primaries coords must be set, either none must be set */ any_set = coords->red_x != 0 || coords->red_y != 0 || coords->green_x != 0 || coords->green_y != 0 || coords->blue_x != 0 || coords->blue_y != 0; all_set = coords->red_x != 0 && coords->red_y != 0 && coords->green_x != 0 && coords->green_y != 0 && coords->blue_x != 0 && coords->blue_y != 0; if (any_set && !all_set) { add_failure(edid, "Some but not all primaries coordinates are unset."); } /* Both white-point coords must be set */ if (coords->white_x == 0 || coords->white_y == 0) { add_failure(edid, "White-point coordinates are unset."); } } static void parse_established_timings_i_ii(struct di_edid *edid, const uint8_t data[static_array EDID_BLOCK_SIZE]) { struct di_edid_established_timings_i_ii *timings = &edid->established_timings_i_ii; timings->has_720x400_70hz = has_bit(data[0x23], 7); timings->has_720x400_88hz = has_bit(data[0x23], 6); timings->has_640x480_60hz = has_bit(data[0x23], 5); timings->has_640x480_67hz = has_bit(data[0x23], 4); timings->has_640x480_72hz = has_bit(data[0x23], 3); timings->has_640x480_75hz = has_bit(data[0x23], 2); timings->has_800x600_56hz = has_bit(data[0x23], 1); timings->has_800x600_60hz = has_bit(data[0x23], 0); /* Established timings II */ timings->has_800x600_72hz = has_bit(data[0x24], 7); timings->has_800x600_75hz = has_bit(data[0x24], 6); timings->has_832x624_75hz = has_bit(data[0x24], 5); timings->has_1024x768_87hz_interlaced = has_bit(data[0x24], 4); timings->has_1024x768_60hz = has_bit(data[0x24], 3); timings->has_1024x768_70hz = has_bit(data[0x24], 2); timings->has_1024x768_75hz = has_bit(data[0x24], 1); timings->has_1280x1024_75hz = has_bit(data[0x24], 0); timings->has_1152x870_75hz = has_bit(data[0x25], 7); /* TODO: manufacturer specified timings in bits 6:0 */ } static bool parse_standard_timing(struct di_edid *edid, const uint8_t data[static_array EDID_STANDARD_TIMING_SIZE], struct di_edid_standard_timing **out) { struct di_edid_standard_timing *t; *out = NULL; if (data[0] == 0x01 && data[1] == 0x01) { /* Unused */ return true; } if (data[0] == 0x00) { add_failure_until(edid, 4, "Use 0x0101 as the invalid Standard Timings code, not 0x%02x%02x.", data[0], data[1]); return true; } t = calloc(1, sizeof(*t)); if (!t) { return false; } t->horiz_video = ((int32_t) data[0] + 31) * 8; t->aspect_ratio = get_bit_range(data[1], 7, 6); t->refresh_rate_hz = (int32_t) get_bit_range(data[1], 5, 0) + 60; *out = t; return true; } struct di_edid_detailed_timing_def_priv * _di_edid_parse_detailed_timing_def(const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE]) { struct di_edid_detailed_timing_def_priv *priv; struct di_edid_detailed_timing_def *def; struct di_edid_detailed_timing_analog_composite *analog_composite; struct di_edid_detailed_timing_bipolar_analog_composite *bipolar_analog_composite; struct di_edid_detailed_timing_digital_composite *digital_composite; struct di_edid_detailed_timing_digital_separate *digital_separate; int raw; uint8_t flags, stereo_hi, stereo_lo; priv = calloc(1, sizeof(*priv)); if (!priv) { return NULL; } def = &priv->base; raw = (data[1] << 8) | data[0]; def->pixel_clock_hz = raw * 10 * 1000; def->horiz_video = (get_bit_range(data[4], 7, 4) << 8) | data[2]; def->horiz_blank = (get_bit_range(data[4], 3, 0) << 8) | data[3]; def->vert_video = (get_bit_range(data[7], 7, 4) << 8) | data[5]; def->vert_blank = (get_bit_range(data[7], 3, 0) << 8) | data[6]; def->horiz_front_porch = (get_bit_range(data[11], 7, 6) << 8) | data[8]; def->horiz_sync_pulse = (get_bit_range(data[11], 5, 4) << 8) | data[9]; def->vert_front_porch = (get_bit_range(data[11], 3, 2) << 4) | get_bit_range(data[10], 7, 4); def->vert_sync_pulse = (get_bit_range(data[11], 1, 0) << 4) | get_bit_range(data[10], 3, 0); def->horiz_image_mm = (get_bit_range(data[14], 7, 4) << 8) | data[12]; def->vert_image_mm = (get_bit_range(data[14], 3, 0) << 8) | data[13]; if ((def->horiz_image_mm == 16 && def->vert_image_mm == 9) || (def->horiz_image_mm == 4 && def->vert_image_mm == 3)) { /* Table 3.21 note 18.2: these are special cases and define the * aspect ratio rather than the size in mm. * TODO: expose these values */ def->horiz_image_mm = def->vert_image_mm = 0; } def->horiz_border = data[15]; def->vert_border = data[16]; flags = data[17]; def->interlaced = has_bit(flags, 7); stereo_hi = get_bit_range(flags, 6, 5); stereo_lo = get_bit_range(flags, 0, 0); if (stereo_hi == 0) { def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE; } else { switch ((stereo_hi << 1) | stereo_lo) { case (1 << 1) | 0: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_RIGHT; break; case (2 << 1) | 0: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_LEFT; break; case (1 << 1) | 1: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_RIGHT; break; case (2 << 1) | 1: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_LEFT; break; case (3 << 1) | 0: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_4_WAY_INTERLEAVED; break; case (3 << 1) | 1: def->stereo = DI_EDID_DETAILED_TIMING_DEF_STEREO_SIDE_BY_SIDE_INTERLEAVED; break; default: abort(); /* unreachable */ } } def->signal_type = get_bit_range(flags, 4, 3); switch (def->signal_type) { case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE: analog_composite = &priv->analog_composite; analog_composite->sync_serrations = has_bit(flags, 2); analog_composite->sync_on_green = has_bit(flags, 1); def->analog_composite = analog_composite; break; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE: bipolar_analog_composite = &priv->bipolar_analog_composite; bipolar_analog_composite->sync_serrations = has_bit(flags, 2); bipolar_analog_composite->sync_on_green = has_bit(flags, 1); def->bipolar_analog_composite = bipolar_analog_composite; break; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE: digital_composite = &priv->digital_composite; digital_composite->sync_serrations = has_bit(flags, 2); digital_composite->sync_horiz_polarity = has_bit(flags, 1); def->digital_composite = digital_composite; break; case DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE: digital_separate = &priv->digital_separate; digital_separate->sync_vert_polarity = has_bit(flags, 2); digital_separate->sync_horiz_polarity = has_bit(flags, 1); def->digital_separate = digital_separate; break; } return priv; } static bool decode_display_range_limits_offset(struct di_edid *edid, uint8_t flags, int *max_offset, int *min_offset) { switch (flags) { case 0x00: /* No offset */ break; case 0x02: *max_offset = 255; break; case 0x03: *max_offset = 255; *min_offset = 255; break; default: add_failure_until(edid, 4, "Range offset flags set to reserved value 0x%02x.", flags); return false; } return true; } static bool parse_display_range_limits(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE], struct di_edid_display_range_limits_priv *priv) { uint8_t offset_flags, vert_offset_flags, horiz_offset_flags; uint8_t support_flags, preferred_aspect_ratio; int max_vert_offset = 0, min_vert_offset = 0; int max_horiz_offset = 0, min_horiz_offset = 0; size_t i; struct di_edid_display_range_limits *base; struct di_edid_display_range_limits_secondary_gtf *secondary_gtf; struct di_edid_display_range_limits_cvt *cvt; base = &priv->base; offset_flags = data[4]; if (edid->revision >= 4) { vert_offset_flags = get_bit_range(offset_flags, 1, 0); horiz_offset_flags = get_bit_range(offset_flags, 3, 2); if (!decode_display_range_limits_offset(edid, vert_offset_flags, &max_vert_offset, &min_vert_offset)) { return false; } if (!decode_display_range_limits_offset(edid, horiz_offset_flags, &max_horiz_offset, &min_horiz_offset)) { return false; } if (edid->revision <= 4 && get_bit_range(offset_flags, 7, 4) != 0) { add_failure(edid, "Display Range Limits: Bits 7:4 of the range offset flags are reserved."); } } else if (offset_flags != 0) { add_failure(edid, "Display Range Limits: Range offset flags are unsupported in EDID 1.3."); } if (edid->revision <= 4 && (data[5] == 0 || data[6] == 0 || data[7] == 0 || data[8] == 0)) { add_failure(edid, "Display Range Limits: Range limits set to reserved values."); return false; } base->min_vert_rate_hz = data[5] + min_vert_offset; base->max_vert_rate_hz = data[6] + max_vert_offset; base->min_horiz_rate_hz = (data[7] + min_horiz_offset) * 1000; base->max_horiz_rate_hz = (data[8] + max_horiz_offset) * 1000; if (base->min_vert_rate_hz > base->max_vert_rate_hz) { add_failure(edid, "Display Range Limits: Min vertical rate > max vertical rate."); return false; } if (base->min_horiz_rate_hz > base->max_horiz_rate_hz) { add_failure(edid, "Display Range Limits: Min horizontal freq > max horizontal freq."); return false; } base->max_pixel_clock_hz = (int32_t) data[9] * 10 * 1000 * 1000; if (edid->revision == 4 && base->max_pixel_clock_hz == 0) { add_failure(edid, "Display Range Limits: EDID 1.4 block does not set max dotclock."); } support_flags = data[10]; switch (support_flags) { case 0x00: /* For EDID 1.4 and later, always indicates support for default * GTF. For EDID 1.3 and earlier, a misc features bit indicates * support for default GTF. */ if (edid->revision >= 4 || edid->misc_features.default_gtf) { base->type = DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF; } else { base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE; } break; case 0x01: if (edid->revision < 4) { /* Reserved */ add_failure(edid, "Display Range Limits: 'Bare Limits' is not allowed for EDID < 1.4."); return false; } base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE; break; case 0x02: base->type = DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF; break; case 0x04: if (edid->revision < 4) { /* Reserved */ add_failure(edid, "Display Range Limits: 'CVT' is not allowed for EDID < 1.4."); return false; } base->type = DI_EDID_DISPLAY_RANGE_LIMITS_CVT; break; default: /* Reserved */ if (edid->revision <= 4) { add_failure(edid, "Display Range Limits: Unknown range class (0x%02x).", support_flags); return false; } base->type = DI_EDID_DISPLAY_RANGE_LIMITS_BARE; break; } /* Some types require the display to support continuous frequencies, but * this flag is only set for EDID 1.4 and later */ if (edid->revision >= 4 && !edid->misc_features.continuous_freq) { switch (base->type) { case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF: case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF: add_failure(edid, "Display Range Limits: GTF can't be combined with non-continuous frequencies."); return false; case DI_EDID_DISPLAY_RANGE_LIMITS_CVT: add_failure(edid, "Display Range Limits: CVT can't be combined with non-continuous frequencies."); return false; default: break; } } switch (base->type) { case DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF: secondary_gtf = &priv->secondary_gtf; if (data[11] != 0) add_failure(edid, "Display Range Limits: Byte 11 is 0x%02x instead of 0x00.", data[11]); secondary_gtf->start_freq_hz = data[12] * 2 * 1000; secondary_gtf->c = (float) data[13] / 2; secondary_gtf->m = (float) ((data[15] << 8) | data[14]); secondary_gtf->k = (float) data[16]; secondary_gtf->j = (float) data[17] / 2; base->secondary_gtf = secondary_gtf; break; case DI_EDID_DISPLAY_RANGE_LIMITS_CVT: cvt = &priv->cvt; cvt->version = get_bit_range(data[11], 7, 4); cvt->revision = get_bit_range(data[11], 3, 0); base->max_pixel_clock_hz -= get_bit_range(data[12], 7, 2) * 250 * 1000; cvt->max_horiz_px = 8 * ((get_bit_range(data[12], 1, 0) << 8) | data[13]); cvt->supported_aspect_ratio = data[14]; if (get_bit_range(data[14], 2, 0) != 0) add_failure_until(edid, 4, "Display Range Limits: Reserved bits of byte 14 are non-zero."); preferred_aspect_ratio = get_bit_range(data[15], 7, 5); switch (preferred_aspect_ratio) { case 0: cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_4_3; break; case 1: cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_9; break; case 2: cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_10; break; case 3: cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_5_4; break; case 4: cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_15_9; break; default: /* Reserved */ add_failure_until(edid, 4, "Display Range Limits: Invalid preferred aspect ratio 0x%02x.", preferred_aspect_ratio); return false; } cvt->standard_blanking = has_bit(data[15], 3); cvt->reduced_blanking = has_bit(data[15], 4); if (get_bit_range(data[15], 2, 0) != 0) add_failure_until(edid, 4, "Display Range Limits: Reserved bits of byte 15 are non-zero."); cvt->supported_scaling = data[16]; if (get_bit_range(data[16], 3, 0) != 0) add_failure_until(edid, 4, "Display Range Limits: Reserved bits of byte 16 are non-zero."); cvt->preferred_vert_refresh_hz = data[17]; if (cvt->preferred_vert_refresh_hz == 0) { add_failure_until(edid, 4, "Display Range Limits: Preferred vertical refresh rate must be specified."); return false; } base->cvt = cvt; break; case DI_EDID_DISPLAY_RANGE_LIMITS_BARE: case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF: if (data[11] != 0x0A) add_failure(edid, "Display Range Limits: Byte 11 is 0x%02x instead of 0x0a.", data[11]); for (i = 12; i < EDID_BYTE_DESCRIPTOR_SIZE; i++) { if (data[i] != 0x20) { add_failure(edid, "Display Range Limits: Bytes 12-17 must be 0x20."); break; } } break; } return true; } static bool parse_standard_timings_descriptor(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE], struct di_edid_display_descriptor *desc) { struct di_edid_standard_timing *t; size_t i; const uint8_t *timing_data; for (i = 0; i < EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT; i++) { timing_data = &data[5 + i * EDID_STANDARD_TIMING_SIZE]; if (!parse_standard_timing(edid, timing_data, &t)) return false; if (t) { assert(desc->standard_timings_len < EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT); desc->standard_timings[desc->standard_timings_len++] = t; } } if (data[17] != 0x0A) add_failure_until(edid, 4, "Standard Timing Identifications: Last byte must be a line feed."); return true; } /** * Mapping table for established timings III. * * Contains one entry per bit, with the value set to the DMT ID. */ static const uint8_t established_timings_iii[] = { /* 0x06 */ 0x01, /* 640 x 350 @ 85 Hz */ 0x02, /* 640 x 400 @ 85 Hz */ 0x03, /* 720 x 400 @ 85 Hz */ 0x07, /* 640 x 480 @ 85 Hz */ 0x0e, /* 848 x 480 @ 60 Hz */ 0x0c, /* 800 x 600 @ 85 Hz */ 0x13, /* 1024 x 768 @ 85 Hz */ 0x15, /* 1152 x 864 @ 75 Hz */ /* 0x07 */ 0x16, /* 1280 x 768 @ 60 Hz (RB) */ 0x17, /* 1280 x 768 @ 60 Hz */ 0x18, /* 1280 x 768 @ 75 Hz */ 0x19, /* 1280 x 768 @ 85 Hz */ 0x20, /* 1280 x 960 @ 60 Hz */ 0x21, /* 1280 x 960 @ 85 Hz */ 0x23, /* 1280 x 1024 @ 60 Hz */ 0x25, /* 1280 x 1024 @ 85 Hz */ /* 0x08 */ 0x27, /* 1360 x 768 @ 60 Hz */ 0x2e, /* 1440 x 900 @ 60 Hz (RB) */ 0x2f, /* 1440 x 900 @ 60 Hz */ 0x30, /* 1440 x 900 @ 75 Hz */ 0x31, /* 1440 x 900 @ 85 Hz */ 0x29, /* 1400 x 1050 @ 60 Hz (RB) */ 0x2a, /* 1400 x 1050 @ 60 Hz */ 0x2b, /* 1400 x 1050 @ 75 Hz */ /* 0x09 */ 0x2c, /* 1400 x 1050 @ 85 Hz */ 0x39, /* 1680 x 1050 @ 60 Hz (RB) */ 0x3a, /* 1680 x 1050 @ 60 Hz */ 0x3b, /* 1680 x 1050 @ 75 Hz */ 0x3c, /* 1680 x 1050 @ 85 Hz */ 0x33, /* 1600 x 1200 @ 60 Hz */ 0x34, /* 1600 x 1200 @ 65 Hz */ 0x35, /* 1600 x 1200 @ 70 Hz */ /* 0x0a */ 0x36, /* 1600 x 1200 @ 75 Hz */ 0x37, /* 1600 x 1200 @ 85 Hz */ 0x3e, /* 1792 x 1344 @ 60 Hz */ 0x3f, /* 1792 x 1344 @ 75 Hz */ 0x41, /* 1856 x 1392 @ 60 Hz */ 0x42, /* 1856 x 1392 @ 75 Hz */ 0x44, /* 1920 x 1200 @ 60 Hz (RB) */ 0x45, /* 1920 x 1200 @ 60 Hz */ /* 0x0b */ 0x46, /* 1920 x 1200 @ 75 Hz */ 0x47, /* 1920 x 1200 @ 85 Hz */ 0x49, /* 1920 x 1440 @ 60 Hz */ 0x4a, /* 1920 x 1440 @ 75 Hz */ }; static_assert(EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT == sizeof(established_timings_iii) / sizeof(established_timings_iii[0]), "Invalid number of established timings III in table"); static const struct di_dmt_timing * get_dmt_timing(uint8_t dmt_id) { size_t i; const struct di_dmt_timing *t; for (i = 0; i < _di_dmt_timings_len; i++) { t = &_di_dmt_timings[i]; if (t->dmt_id == dmt_id) return t; } return NULL; } static void parse_established_timings_iii_descriptor(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE], struct di_edid_display_descriptor *desc) { size_t i, offset, bit; uint8_t dmt_id; const struct di_dmt_timing *t; bool has_zeroes; if (edid->revision < 4) add_failure(edid, "Established timings III: Not allowed for EDID < 1.4."); for (i = 0; i < EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT; i++) { dmt_id = established_timings_iii[i]; offset = 0x06 + i / 8; bit = 7 - i % 8; assert(offset < EDID_BYTE_DESCRIPTOR_SIZE); if (has_bit(data[offset], bit)) { t = get_dmt_timing(dmt_id); assert(t != NULL); desc->established_timings_iii[desc->established_timings_iii_len++] = t; } } has_zeroes = get_bit_range(data[11], 3, 0) == 0; for (i = 12; i < EDID_BYTE_DESCRIPTOR_SIZE; i++) { has_zeroes = has_zeroes && data[i] == 0; } if (!has_zeroes) { add_failure_until(edid, 4, "Established timings III: Reserved bits must be set to zero."); } } static bool parse_color_point_descriptor(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE], struct di_edid_display_descriptor *desc) { struct di_edid_color_point *c; if (data[5] == 0) { add_failure(edid, "White Point Index Number set to reserved value 0"); } c = calloc(1, sizeof(*c)); if (!c) { return false; } c->index = data[5]; c->white_x = decode_chromaticity_coord(data[7], get_bit_range(data[6], 3, 2)); c->white_y = decode_chromaticity_coord(data[8], get_bit_range(data[6], 1, 0)); if (data[9] != 0xFF) { c->gamma = ((float) data[9] + 100) / 100; } desc->color_points[desc->color_points_len++] = c; if (data[10] == 0) { return true; } c = calloc(1, sizeof(*c)); if (!c) { return false; } c->index = data[10]; c->white_x = decode_chromaticity_coord(data[12], get_bit_range(data[11], 3, 2)); c->white_y = decode_chromaticity_coord(data[13], get_bit_range(data[11], 1, 0)); if (data[14] != 0xFF) { c->gamma = ((float) data[14] + 100) / 100; } desc->color_points[desc->color_points_len++] = c; return true; } static void parse_color_management_data_descriptor(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE], struct di_edid_display_descriptor *desc) { desc->dcm_data.version = data[5]; desc->dcm_data.red_a3 = (uint16_t)(data[6] | (data[7] << 8)) / 100.0f; desc->dcm_data.red_a2 = (uint16_t)(data[8] | (data[9] << 8)) / 100.0f; desc->dcm_data.green_a3 = (uint16_t)(data[10] | (data[11] << 8)) / 100.0f; desc->dcm_data.green_a2 = (uint16_t)(data[12] | (data[13] << 8)) / 100.0f; desc->dcm_data.blue_a3 = (uint16_t)(data[14] | (data[15] << 8)) / 100.0f; desc->dcm_data.blue_a2 = (uint16_t)(data[16] | (data[17] << 8)) / 100.0f; if (desc->dcm_data.version != 3) { add_failure_until(edid, 4, "Color Management Data version must be 3"); } } static bool parse_byte_descriptor(struct di_edid *edid, const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE]) { struct di_edid_display_descriptor *desc; struct di_edid_detailed_timing_def_priv *detailed_timing_def; uint8_t tag; char *newline; if (data[0] || data[1]) { if (edid->display_descriptors_len > 0) { /* A detailed timing descriptor is not allowed after a * display descriptor per note 3 of table 3.20. */ add_failure(edid, "Invalid detailed timing descriptor ordering."); } detailed_timing_def = _di_edid_parse_detailed_timing_def(data); if (!detailed_timing_def) { return false; } assert(edid->detailed_timing_defs_len < EDID_BYTE_DESCRIPTOR_COUNT); edid->detailed_timing_defs[edid->detailed_timing_defs_len++] = detailed_timing_def; return true; } if (edid->revision >= 3 && edid->revision <= 4 && edid->detailed_timing_defs_len == 0) { /* Per section 3.10.1 */ add_failure(edid, "The first byte descriptor must contain the preferred timing."); } desc = calloc(1, sizeof(*desc)); if (!desc) { return false; } tag = data[3]; switch (tag) { case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL: case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING: case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME: memcpy(desc->str, &data[5], 13); /* A newline (if any) indicates the end of the string. */ newline = strchr(desc->str, '\n'); if (newline) { newline[0] = '\0'; } break; case DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS: if (!parse_display_range_limits(edid, data, &desc->range_limits)) { free(desc); return true; } break; case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS: if (!parse_standard_timings_descriptor(edid, data, desc)) { free(desc); return false; } break; case DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III: parse_established_timings_iii_descriptor(edid, data, desc); break; case DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT: if (!parse_color_point_descriptor(edid, data, desc)) { free(desc); return false; } break; case DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA: parse_color_management_data_descriptor(edid, data, desc); break; case DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES: case DI_EDID_DISPLAY_DESCRIPTOR_DUMMY: break; /* Ignore */ default: free(desc); if (tag <= 0x0F) { /* Manufacturer-specific */ } else { add_failure_until(edid, 4, "Unknown Type 0x%02hhx.", tag); } return true; } desc->tag = tag; assert(edid->display_descriptors_len < EDID_BYTE_DESCRIPTOR_COUNT); edid->display_descriptors[edid->display_descriptors_len++] = desc; return true; } static bool parse_ext(struct di_edid *edid, const uint8_t data[static_array EDID_BLOCK_SIZE]) { struct di_edid_ext *ext; uint8_t tag; struct di_logger logger; char section_name[64]; if (!validate_block_checksum(data)) { errno = EINVAL; return false; } ext = calloc(1, sizeof(*ext)); if (!ext) { return false; } tag = data[0x00]; switch (tag) { case DI_EDID_EXT_CEA: snprintf(section_name, sizeof(section_name), "Block %zu, CTA-861 Extension Block", edid->exts_len + 1); logger = (struct di_logger) { .f = edid->logger->f, .section = section_name, }; if (!_di_edid_cta_parse(&ext->cta, data, EDID_BLOCK_SIZE, &logger)) { free(ext); return false; } break; case DI_EDID_EXT_VTB: case DI_EDID_EXT_DI: case DI_EDID_EXT_LS: case DI_EDID_EXT_DPVL: case DI_EDID_EXT_BLOCK_MAP: case DI_EDID_EXT_VENDOR: /* Supported */ break; case DI_EDID_EXT_DISPLAYID: snprintf(section_name, sizeof(section_name), "Block %zu, DisplayID Extension Block", edid->exts_len + 1); logger = (struct di_logger) { .f = edid->logger->f, .section = section_name, }; if (!_di_displayid_parse(&ext->displayid, &data[1], EDID_BLOCK_SIZE - 2, &logger)) { free(ext); return false; } break; default: /* Unsupported */ free(ext); add_failure_until(edid, 4, "Unknown Extension Block."); return true; } ext->tag = tag; assert(edid->exts_len < EDID_MAX_BLOCK_COUNT - 1); edid->exts[edid->exts_len++] = ext; return true; } struct di_edid * _di_edid_parse(const void *data, size_t size, FILE *failure_msg_file) { struct di_edid *edid; struct di_logger logger; int version, revision; size_t exts_len, i; const uint8_t *standard_timing_data, *byte_desc_data, *ext_data; struct di_edid_standard_timing *standard_timing; if (size < EDID_BLOCK_SIZE || size > EDID_MAX_BLOCK_COUNT * EDID_BLOCK_SIZE || size % EDID_BLOCK_SIZE != 0) { errno = EINVAL; return NULL; } if (memcmp(data, header, sizeof(header)) != 0) { errno = EINVAL; return NULL; } parse_version_revision(data, &version, &revision); if (version != 1) { /* Only EDID version 1 is supported -- as per section 2.1.7 * subsequent versions break the structure */ errno = ENOTSUP; return NULL; } if (!validate_block_checksum(data)) { errno = EINVAL; return NULL; } exts_len = size / EDID_BLOCK_SIZE - 1; if (exts_len != parse_ext_count(data)) { errno = EINVAL; return NULL; } edid = calloc(1, sizeof(*edid)); if (!edid) { return NULL; } logger = (struct di_logger) { .f = failure_msg_file, .section = "Block 0, Base EDID", }; edid->logger = &logger; edid->version = version; edid->revision = revision; parse_vendor_product(edid, data); parse_basic_params_features(edid, data); parse_chromaticity_coords(edid, data); parse_established_timings_i_ii(edid, data); for (i = 0; i < EDID_MAX_STANDARD_TIMING_COUNT; i++) { standard_timing_data = (const uint8_t *) data + 0x26 + i * EDID_STANDARD_TIMING_SIZE; if (!parse_standard_timing(edid, standard_timing_data, &standard_timing)) { _di_edid_destroy(edid); return NULL; } if (standard_timing) { assert(edid->standard_timings_len < EDID_MAX_STANDARD_TIMING_COUNT); edid->standard_timings[edid->standard_timings_len++] = standard_timing; } } for (i = 0; i < EDID_BYTE_DESCRIPTOR_COUNT; i++) { byte_desc_data = (const uint8_t *) data + 0x36 + i * EDID_BYTE_DESCRIPTOR_SIZE; if (!parse_byte_descriptor(edid, byte_desc_data)) { _di_edid_destroy(edid); return NULL; } } for (i = 0; i < exts_len; i++) { ext_data = (const uint8_t *) data + (i + 1) * EDID_BLOCK_SIZE; if (!parse_ext(edid, ext_data)) { _di_edid_destroy(edid); return NULL; } } edid->logger = NULL; return edid; } static void destroy_display_descriptor(struct di_edid_display_descriptor *desc) { size_t i; switch (desc->tag) { case DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS: for (i = 0; i < desc->standard_timings_len; i++) { free(desc->standard_timings[i]); } break; default: break; /* Nothing to do */ } free(desc); } void _di_edid_destroy(struct di_edid *edid) { size_t i; struct di_edid_ext *ext; for (i = 0; i < edid->standard_timings_len; i++) { free(edid->standard_timings[i]); } for (i = 0; i < edid->detailed_timing_defs_len; i++) { free(edid->detailed_timing_defs[i]); } for (i = 0; i < edid->display_descriptors_len; i++) { destroy_display_descriptor(edid->display_descriptors[i]); } for (i = 0; edid->exts[i] != NULL; i++) { ext = edid->exts[i]; switch (ext->tag) { case DI_EDID_EXT_CEA: _di_edid_cta_finish(&ext->cta); break; case DI_EDID_EXT_DISPLAYID: _di_displayid_finish(&ext->displayid); break; default: break; /* Nothing to do */ } free(ext); } free(edid); } int di_edid_get_version(const struct di_edid *edid) { return edid->version; } int di_edid_get_revision(const struct di_edid *edid) { return edid->revision; } const struct di_edid_vendor_product * di_edid_get_vendor_product(const struct di_edid *edid) { return &edid->vendor_product; } const struct di_edid_video_input_analog * di_edid_get_video_input_analog(const struct di_edid *edid) { return edid->is_digital ? NULL : &edid->video_input_analog; } const struct di_edid_video_input_digital * di_edid_get_video_input_digital(const struct di_edid *edid) { return edid->is_digital ? &edid->video_input_digital : NULL; } const struct di_edid_screen_size * di_edid_get_screen_size(const struct di_edid *edid) { return &edid->screen_size; } float di_edid_get_basic_gamma(const struct di_edid *edid) { return edid->gamma; } const struct di_edid_dpms * di_edid_get_dpms(const struct di_edid *edid) { return &edid->dpms; } enum di_edid_display_color_type di_edid_get_display_color_type(const struct di_edid *edid) { return edid->display_color_type; } const struct di_edid_color_encoding_formats * di_edid_get_color_encoding_formats(const struct di_edid *edid) { /* If color encoding formats are specified, RGB 4:4:4 is always * supported. */ return edid->color_encoding_formats.rgb444 ? &edid->color_encoding_formats : NULL; } const struct di_edid_misc_features * di_edid_get_misc_features(const struct di_edid *edid) { return &edid->misc_features; } const struct di_edid_chromaticity_coords * di_edid_get_chromaticity_coords(const struct di_edid *edid) { return &edid->chromaticity_coords; } const struct di_edid_established_timings_i_ii * di_edid_get_established_timings_i_ii(const struct di_edid *edid) { return &edid->established_timings_i_ii; } int32_t di_edid_standard_timing_get_vert_video(const struct di_edid_standard_timing *t) { switch (t->aspect_ratio) { case DI_EDID_STANDARD_TIMING_16_10: return t->horiz_video * 10 / 16; case DI_EDID_STANDARD_TIMING_4_3: return t->horiz_video * 3 / 4; case DI_EDID_STANDARD_TIMING_5_4: return t->horiz_video * 4 / 5; case DI_EDID_STANDARD_TIMING_16_9: return t->horiz_video * 9 / 16; } abort(); /* unreachable */ } const struct di_dmt_timing * di_edid_standard_timing_get_dmt(const struct di_edid_standard_timing *t) { int32_t vert_video; size_t i; const struct di_dmt_timing *dmt; vert_video = di_edid_standard_timing_get_vert_video(t); for (i = 0; i < _di_dmt_timings_len; i++) { dmt = &_di_dmt_timings[i]; if (dmt->horiz_video == t->horiz_video && dmt->vert_video == vert_video && dmt->refresh_rate_hz == (float)t->refresh_rate_hz && dmt->edid_std_id != 0) { return dmt; } } return 0; } const struct di_edid_standard_timing *const * di_edid_get_standard_timings(const struct di_edid *edid) { return (const struct di_edid_standard_timing *const *) &edid->standard_timings; } const struct di_edid_detailed_timing_def *const * di_edid_get_detailed_timing_defs(const struct di_edid *edid) { return (const struct di_edid_detailed_timing_def *const *) &edid->detailed_timing_defs; } const struct di_edid_display_descriptor *const * di_edid_get_display_descriptors(const struct di_edid *edid) { return (const struct di_edid_display_descriptor *const *) &edid->display_descriptors; } enum di_edid_display_descriptor_tag di_edid_display_descriptor_get_tag(const struct di_edid_display_descriptor *desc) { return desc->tag; } const char * di_edid_display_descriptor_get_string(const struct di_edid_display_descriptor *desc) { switch (desc->tag) { case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL: case DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING: case DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME: return desc->str; default: return NULL; } } const struct di_edid_display_range_limits * di_edid_display_descriptor_get_range_limits(const struct di_edid_display_descriptor *desc) { if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS) { return NULL; } return &desc->range_limits.base; } const struct di_edid_standard_timing *const * di_edid_display_descriptor_get_standard_timings(const struct di_edid_display_descriptor *desc) { if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS) { return NULL; } return (const struct di_edid_standard_timing *const *) desc->standard_timings; } const struct di_edid_color_point *const * di_edid_display_descriptor_get_color_points(const struct di_edid_display_descriptor *desc) { if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT) { return NULL; } return (const struct di_edid_color_point *const *) desc->color_points; } const struct di_dmt_timing *const * di_edid_display_descriptor_get_established_timings_iii(const struct di_edid_display_descriptor *desc) { if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III) { return NULL; } return desc->established_timings_iii; } const struct di_edid_color_management_data * di_edid_display_descriptor_get_color_management_data(const struct di_edid_display_descriptor *desc) { if (desc->tag != DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA) { return NULL; } return &desc->dcm_data; } const struct di_edid_ext *const * di_edid_get_extensions(const struct di_edid *edid) { return (const struct di_edid_ext *const *) edid->exts; } enum di_edid_ext_tag di_edid_ext_get_tag(const struct di_edid_ext *ext) { return ext->tag; } const struct di_edid_cta * di_edid_ext_get_cta(const struct di_edid_ext *ext) { if (ext->tag != DI_EDID_EXT_CEA) { return NULL; } return &ext->cta; } const struct di_displayid * di_edid_ext_get_displayid(const struct di_edid_ext *ext) { if (ext->tag != DI_EDID_EXT_DISPLAYID) { return NULL; } return &ext->displayid; } dxvk-0~git20230309.275e645/gtf.c000066400000000000000000000110111440230200600155410ustar00rootroot00000000000000/* * Copyright 2006-2012 Red Hat, Inc. * Copyright 2018-2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. * * Originally imported from edid-decode. */ #include #include /** * The assumed character cell granularity of the graphics system, in pixels. */ #define CELL_GRAN 8.0 /** * The size of the top and bottom overscan margin as a percentage of the active * vertical image. */ #define MARGIN_PERC 1.8 /** * The minimum front porch in lines (vertical) and character cells (horizontal). */ #define MIN_PORCH 1.0 /** * The width of the V sync in lines. */ #define V_SYNC_RQD 3.0 /** * The width of the H sync as a percentage of the total line period. */ #define H_SYNC_PERC 8.0 /** * Minimum time of vertical sync + back porch interval (µs). */ #define MIN_VSYNC_BP 550.0 void di_gtf_compute(struct di_gtf_timing *t, const struct di_gtf_options *options) { double c_prime, m_prime, h_pixels_rnd, v_lines_rnd, h_margin, v_margin, interlace, total_active_pixels, pixel_freq = 0.0, h_blank_pixels = 0.0, total_pixels = 0.0, v_sync_bp = 0.0, v_field_rate_rqd, h_period_est, total_v_lines, v_field_rate_est, h_period, ideal_duty_cycle, h_freq, ideal_h_period, v_back_porch, h_sync, h_front_porch; /* C' and M' are part of the Blanking Duty Cycle computation */ c_prime = ((options->c - options->j) * options->k / 256.0) + options->j; m_prime = options->k / 256.0 * options->m; h_pixels_rnd = round(options->h_pixels / CELL_GRAN) * CELL_GRAN; v_lines_rnd = options->int_rqd ? round(options->v_lines / 2.0) : options->v_lines; h_margin = options->margins_rqd ? round(h_pixels_rnd * MARGIN_PERC / 100.0 / CELL_GRAN) * CELL_GRAN : 0; v_margin = options->margins_rqd ? round(MARGIN_PERC / 100.0 * v_lines_rnd) : 0; interlace = options->int_rqd ? 0.5 : 0; total_active_pixels = h_pixels_rnd + h_margin * 2; switch (options->ip_param) { case DI_GTF_IP_PARAM_V_FRAME_RATE: // vertical frame frequency (Hz) v_field_rate_rqd = options->int_rqd ? options->ip_freq_rqd * 2 : options->ip_freq_rqd; h_period_est = (1.0 / v_field_rate_rqd - MIN_VSYNC_BP / 1000000.0) / (v_lines_rnd + v_margin * 2 + MIN_PORCH + interlace) * 1000000.0; v_sync_bp = round(MIN_VSYNC_BP / h_period_est); total_v_lines = v_lines_rnd + v_margin * 2 + v_sync_bp + interlace + MIN_PORCH; v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); ideal_duty_cycle = c_prime - m_prime * h_period / 1000.0; h_blank_pixels = round(total_active_pixels * ideal_duty_cycle / (100.0 - ideal_duty_cycle) / (2 * CELL_GRAN)) * 2 * CELL_GRAN; total_pixels = total_active_pixels + h_blank_pixels; pixel_freq = total_pixels / h_period; break; case DI_GTF_IP_PARAM_H_FREQ: // horizontal frequency (kHz) h_freq = options->ip_freq_rqd; v_sync_bp = round(MIN_VSYNC_BP * h_freq / 1000.0); ideal_duty_cycle = c_prime - m_prime / h_freq; h_blank_pixels = round(total_active_pixels * ideal_duty_cycle / (100.0 - ideal_duty_cycle) / (2 * CELL_GRAN)) * 2 * CELL_GRAN; total_pixels = total_active_pixels + h_blank_pixels; pixel_freq = total_pixels * h_freq / 1000.0; break; case DI_GTF_IP_PARAM_H_PIXELS: // pixel clock rate (MHz) pixel_freq = options->ip_freq_rqd; ideal_h_period = (c_prime - 100.0 + sqrt((100.0 - c_prime) * (100.0 - c_prime) + 0.4 * m_prime * (total_active_pixels + h_margin * 2) / pixel_freq)) / 2.0 / m_prime * 1000.0; ideal_duty_cycle = c_prime - m_prime * ideal_h_period / 1000.0; h_blank_pixels = round(total_active_pixels * ideal_duty_cycle / (100.0 - ideal_duty_cycle) / (2 * CELL_GRAN)) * 2 * CELL_GRAN; total_pixels = total_active_pixels + h_blank_pixels; h_freq = pixel_freq / total_pixels * 1000.0; v_sync_bp = round(MIN_VSYNC_BP * h_freq / 1000.0); break; } v_back_porch = v_sync_bp - V_SYNC_RQD; h_sync = round(H_SYNC_PERC / 100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; h_front_porch = h_blank_pixels / 2.0 - h_sync; *t = (struct di_gtf_timing) { .h_pixels = (int) h_pixels_rnd, .v_lines = options->v_lines, .v_sync = (int) V_SYNC_RQD, .h_sync = (int) h_sync, .v_front_porch = (int) MIN_PORCH, .v_back_porch = (int) v_back_porch, .h_front_porch = (int) h_front_porch, .h_back_porch = (int) (h_front_porch + h_sync), .h_border = (int) h_margin, .v_border = (int) v_margin, .pixel_freq_mhz = pixel_freq, }; } dxvk-0~git20230309.275e645/include/000077500000000000000000000000001440230200600162465ustar00rootroot00000000000000dxvk-0~git20230309.275e645/include/bits.h000066400000000000000000000012471440230200600173640ustar00rootroot00000000000000#ifndef BITS_H #define BITS_H /** * Utility functions to operate on bits. */ #include #include #include #include /** * Check whether a byte has a bit set. */ static inline bool has_bit(uint8_t val, size_t index) { return val & (1 << index); } /** * Extract a bit range from a byte. * * Both offsets are inclusive, start from zero, and high must be greater than low. */ static inline uint8_t get_bit_range(uint8_t val, size_t high, size_t low) { size_t n; uint8_t bitmask; assert(high <= 7 && high >= low); n = high - low + 1; bitmask = (uint8_t) ((1 << n) - 1); return (uint8_t) (val >> low) & bitmask; } #endif dxvk-0~git20230309.275e645/include/cta.h000066400000000000000000000045451440230200600171760ustar00rootroot00000000000000#ifndef CTA_H #define CTA_H /** * Private header for the low-level CTA API. */ #include #include #include #include /** * The maximum number of data blocks in an EDID CTA block. * * Each data block takes at least 1 byte, the CTA block can hold 128 bytes, and * the mandatory fields take up 5 bytes (4 header bytes + checksum). */ #define EDID_CTA_MAX_DATA_BLOCKS 123 /** * The maximum number of detailed timing definitions included in an EDID CTA * block. * * The CTA extension leaves at most 122 bytes for timings, and each timing takes * 18 bytes. */ #define EDID_CTA_MAX_DETAILED_TIMING_DEFS 6 /** * The maximum number of SVD entries in a video data block. * * Each data block has its size described in a 5-bit field, so its maximum size * is 63 bytes, and each SVD uses 1 byte. */ #define EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES 63 struct di_edid_cta { int revision; struct di_edid_cta_flags flags; /* NULL-terminated */ struct di_cta_data_block *data_blocks[EDID_CTA_MAX_DATA_BLOCKS + 1]; size_t data_blocks_len; /* NULL-terminated */ struct di_edid_detailed_timing_def_priv *detailed_timing_defs[EDID_CTA_MAX_DETAILED_TIMING_DEFS + 1]; size_t detailed_timing_defs_len; struct di_logger *logger; }; struct di_cta_hdr_static_metadata_block_priv { struct di_cta_hdr_static_metadata_block base; struct di_cta_hdr_static_metadata_block_eotfs eotfs; struct di_cta_hdr_static_metadata_block_descriptors descriptors; }; struct di_cta_video_block { /* NULL-terminated */ struct di_cta_svd *svds[EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES + 1]; size_t svds_len; }; struct di_cta_data_block { enum di_cta_data_block_tag tag; /* Used for DI_CTA_DATA_BLOCK_VIDEO */ struct di_cta_video_block video; /* Used for DI_CTA_DATA_BLOCK_VIDEO_CAP */ struct di_cta_video_cap_block video_cap; /* Used for DI_CTA_DATA_BLOCK_COLORIMETRY */ struct di_cta_colorimetry_block colorimetry; /* Used for DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA */ struct di_cta_hdr_static_metadata_block_priv hdr_static_metadata; /* Used for DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC */ struct di_cta_vesa_transfer_characteristics vesa_transfer_characteristics; }; bool _di_edid_cta_parse(struct di_edid_cta *cta, const uint8_t *data, size_t size, struct di_logger *logger); void _di_edid_cta_finish(struct di_edid_cta *cta); #endif dxvk-0~git20230309.275e645/include/di-edid-decode.h000066400000000000000000000011131440230200600211330ustar00rootroot00000000000000#ifndef DI_EDID_DECODE_H #define DI_EDID_DECODE_H #include struct uncommon_features { bool color_point_descriptor; bool color_management_data; bool cta_transfer_characteristics; }; extern struct uncommon_features uncommon_features; struct di_edid; struct di_edid_detailed_timing_def; struct di_edid_cta; struct di_displayid; void print_edid(const struct di_edid *edid); void print_detailed_timing_def(const struct di_edid_detailed_timing_def *def); void print_cta(const struct di_edid_cta *cta); void print_displayid(const struct di_displayid *displayid); #endif dxvk-0~git20230309.275e645/include/displayid.h000066400000000000000000000030161440230200600204010ustar00rootroot00000000000000#ifndef DISPLAYID_H #define DISPLAYID_H /** * Private header for the low-level DisplayID API. */ #include #include #include #include #include "log.h" /** * The maximum number of data blocks in a DisplayID section. * * A DisplayID section has a payload size of 251 bytes, and each data block has * a minimum size of 3 bytes. */ #define DISPLAYID_MAX_DATA_BLOCKS 83 /** * The maximum number of type I timings in a data block. * * A DisplayID data block has a maximum payload size of 248 bytes, and each type * I timing takes up 20 bytes. */ #define DISPLAYID_MAX_TYPE_I_TIMINGS 12 struct di_displayid { int version, revision; enum di_displayid_product_type product_type; struct di_displayid_data_block *data_blocks[DISPLAYID_MAX_DATA_BLOCKS + 1]; size_t data_blocks_len; struct di_logger *logger; }; struct di_displayid_display_params_priv { struct di_displayid_display_params base; struct di_displayid_display_params_features features; }; struct di_displayid_data_block { enum di_displayid_data_block_tag tag; /* Used for TYPE_I_TIMING, NULL-terminated */ struct di_displayid_type_i_timing *type_i_timings[DISPLAYID_MAX_TYPE_I_TIMINGS + 1]; size_t type_i_timings_len; /* Used for DISPLAY_PARAMS */ struct di_displayid_display_params_priv display_params; }; bool _di_displayid_parse(struct di_displayid *displayid, const uint8_t *data, size_t size, struct di_logger *logger); void _di_displayid_finish(struct di_displayid *displayid); #endif dxvk-0~git20230309.275e645/include/dmt.h000066400000000000000000000003711440230200600172040ustar00rootroot00000000000000#ifndef DMT_H #define DMT_H /** * Private header for VESA Display Monitor Timing. */ #include #include extern const struct di_dmt_timing _di_dmt_timings[]; extern const size_t _di_dmt_timings_len; #endif dxvk-0~git20230309.275e645/include/edid.h000066400000000000000000000107731440230200600173340ustar00rootroot00000000000000#ifndef EDID_H #define EDID_H /** * Private header for the low-level EDID API. */ #include #include #include #include #include "cta.h" #include "displayid.h" /** * The maximum number of EDID blocks (including the base block), defined in * section 2.2.1. */ #define EDID_MAX_BLOCK_COUNT 256 /** * The maximum number of EDID standard timings, defined in section 3.9. */ #define EDID_MAX_STANDARD_TIMING_COUNT 8 /** * The number of EDID byte descriptors, defined in section 3.10. */ #define EDID_BYTE_DESCRIPTOR_COUNT 4 /** * The size of an EDID byte descriptor, defined in section 3.10. */ #define EDID_BYTE_DESCRIPTOR_SIZE 18 /** * The maximum number of standard timings in an EDID display descriptor, defined * in section 3.10.3.6. */ #define EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT 6 /** * The maximum number of color points in an EDID color point descriptor, defined * in section 3.10.3.5. */ #define EDID_MAX_DESCRIPTOR_COLOR_POINT_COUNT 2 /** * The maximum number of established timings III in an EDID display descriptor, * defined in section 3.10.3.9. */ #define EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT 44 struct di_edid_detailed_timing_def_priv { struct di_edid_detailed_timing_def base; struct di_edid_detailed_timing_analog_composite analog_composite; struct di_edid_detailed_timing_bipolar_analog_composite bipolar_analog_composite; struct di_edid_detailed_timing_digital_composite digital_composite; struct di_edid_detailed_timing_digital_separate digital_separate; }; struct di_edid { struct di_edid_vendor_product vendor_product; int version, revision; bool is_digital; struct di_edid_video_input_analog video_input_analog; struct di_edid_video_input_digital video_input_digital; struct di_edid_screen_size screen_size; float gamma; struct di_edid_dpms dpms; enum di_edid_display_color_type display_color_type; struct di_edid_color_encoding_formats color_encoding_formats; struct di_edid_misc_features misc_features; struct di_edid_chromaticity_coords chromaticity_coords; struct di_edid_established_timings_i_ii established_timings_i_ii; /* NULL-terminated */ struct di_edid_standard_timing *standard_timings[EDID_MAX_STANDARD_TIMING_COUNT + 1]; size_t standard_timings_len; /* NULL-terminated */ struct di_edid_detailed_timing_def_priv *detailed_timing_defs[EDID_BYTE_DESCRIPTOR_COUNT + 1]; size_t detailed_timing_defs_len; /* NULL-terminated */ struct di_edid_display_descriptor *display_descriptors[EDID_BYTE_DESCRIPTOR_COUNT + 1]; size_t display_descriptors_len; /* NULL-terminated, doesn't include the base block */ struct di_edid_ext *exts[EDID_MAX_BLOCK_COUNT]; size_t exts_len; struct di_logger *logger; }; struct di_edid_display_range_limits_priv { struct di_edid_display_range_limits base; struct di_edid_display_range_limits_secondary_gtf secondary_gtf; struct di_edid_display_range_limits_cvt cvt; }; struct di_edid_display_descriptor { enum di_edid_display_descriptor_tag tag; /* Used for PRODUCT_SERIAL, DATA_STRING and PRODUCT_NAME, * zero-terminated */ char str[14]; /* Used for RANGE_LIMITS */ struct di_edid_display_range_limits_priv range_limits; /* Used for STD_TIMING_IDS, NULL-terminated */ struct di_edid_standard_timing *standard_timings[EDID_MAX_DESCRIPTOR_STANDARD_TIMING_COUNT + 1]; size_t standard_timings_len; /* Used for COLOR_POINT, NULL-terminated */ struct di_edid_color_point *color_points[EDID_MAX_DESCRIPTOR_COLOR_POINT_COUNT + 1]; size_t color_points_len; /* Used for ESTABLISHED_TIMINGS_III, NULL-terminated */ const struct di_dmt_timing *established_timings_iii[EDID_MAX_DESCRIPTOR_ESTABLISHED_TIMING_III_COUNT + 1]; size_t established_timings_iii_len; /* Used for DCM_DATA */ struct di_edid_color_management_data dcm_data; }; struct di_edid_ext { enum di_edid_ext_tag tag; /* Used for DI_EDID_EXT_CEA */ struct di_edid_cta cta; /* Used for DI_EDID_EXT_DISPLAYID */ struct di_displayid displayid; }; /** * Create an EDID data structure. * * Callers do not need to keep the provided data pointer valid after calling * this function. Callers should destroy the returned pointer via * di_edid_destroy(). */ struct di_edid * _di_edid_parse(const void *data, size_t size, FILE *failure_msg_file); /** * Destroy an EDID data structure. */ void _di_edid_destroy(struct di_edid *edid); /** * Parse an EDID detailed timing definition. */ struct di_edid_detailed_timing_def_priv * _di_edid_parse_detailed_timing_def(const uint8_t data[static_array EDID_BYTE_DESCRIPTOR_SIZE]); #endif dxvk-0~git20230309.275e645/include/info.h000066400000000000000000000002751440230200600173560ustar00rootroot00000000000000#ifndef INFO_H #define INFO_H /** * Private header for the high-level API. */ #include struct di_info { struct di_edid *edid; char *failure_msg; }; #endif dxvk-0~git20230309.275e645/include/libdisplay-info/000077500000000000000000000000001440230200600213335ustar00rootroot00000000000000dxvk-0~git20230309.275e645/include/libdisplay-info/cta.h000066400000000000000000000221561440230200600222610ustar00rootroot00000000000000#ifndef DI_CTA_H #define DI_CTA_H /** * libdisplay-info's low-level API for Consumer Technology Association * standards. * * The library implements CTA-861-H, available at: * https://shop.cta.tech/collections/standards/products/a-dtv-profile-for-uncompressed-high-speed-digital-interfaces-cta-861-h */ #include #include /** * EDID CTA-861 extension block. */ struct di_edid_cta; /** * Get the CTA extension revision (also referred to as "version" by the * specification). */ int di_edid_cta_get_revision(const struct di_edid_cta *cta); /** * Miscellaneous EDID CTA flags, defined in section 7.3.3. * * For CTA revision 1, all of the fields are zero. */ struct di_edid_cta_flags { /* Sink underscans IT Video Formats by default */ bool it_underscan; /* Sink supports Basic Audio */ bool basic_audio; /* Sink supports YCbCr 4:4:4 in addition to RGB */ bool ycc444; /* Sink supports YCbCr 4:2:2 in addition to RGB */ bool ycc422; /* Total number of native detailed timing descriptors */ int native_dtds; }; /** * Get miscellaneous CTA flags. */ const struct di_edid_cta_flags * di_edid_cta_get_flags(const struct di_edid_cta *cta); /** * CTA data block, defined in section 7.4. */ struct di_cta_data_block; /** * Get CTA data blocks. * * The returned array is NULL-terminated. */ const struct di_cta_data_block *const * di_edid_cta_get_data_blocks(const struct di_edid_cta *cta); /** * CTA data block tag. * * Note, the enum values don't match the specification. */ enum di_cta_data_block_tag { /* Audio Data Block */ DI_CTA_DATA_BLOCK_AUDIO = 1, /* Video Data Block */ DI_CTA_DATA_BLOCK_VIDEO, /* Speaker Allocation Data Block */ DI_CTA_DATA_BLOCK_SPEAKER_ALLOC, /* VESA Display Transfer Characteristic Data Block */ DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC, /* Video Capability Data Block */ DI_CTA_DATA_BLOCK_VIDEO_CAP, /* VESA Display Device Data Block */ DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE, /* Colorimetry Data Block */ DI_CTA_DATA_BLOCK_COLORIMETRY, /* HDR Static Metadata Data Block */ DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA, /* HDR Dynamic Metadata Data Block */ DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA, /* Video Format Preference Data Block */ DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF, /* YCbCr 4:2:0 Video Data Block */ DI_CTA_DATA_BLOCK_YCBCR420, /* YCbCr 4:2:0 Capability Map Data Block */ DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP, /* HDMI Audio Data Block */ DI_CTA_DATA_BLOCK_HDMI_AUDIO, /* Room Configuration Data Block */ DI_CTA_DATA_BLOCK_ROOM_CONFIG, /* Speaker Location Data Block */ DI_CTA_DATA_BLOCK_SPEAKER_LOCATION, /* InfoFrame Data Block */ DI_CTA_DATA_BLOCK_INFOFRAME, /* DisplayID Type VII Video Timing Data Block */ DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII, /* DisplayID Type VIII Video Timing Data Block */ DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VIII, /* DisplayID Type X Video Timing Data Block */ DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_X, /* HDMI Forum EDID Extension Override Data Block */ DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE, /* HDMI Forum Sink Capability Data Block */ DI_CTA_DATA_BLOCK_HDMI_SINK_CAP, }; /** * Get the tag of the CTA data block. */ enum di_cta_data_block_tag di_cta_data_block_get_tag(const struct di_cta_data_block *block); /** * Over- and underscan capability. */ enum di_cta_video_cap_over_underscan { /* No data */ DI_CTA_VIDEO_CAP_UNKNOWN_OVER_UNDERSCAN = 0x00, /* Always overscanned */ DI_CTA_VIDEO_CAP_ALWAYS_OVERSCAN = 0x01, /* Always underscanned */ DI_CTA_VIDEO_CAP_ALWAYS_UNDERSCAN = 0x02, /* Supports both over- and underscan */ DI_CTA_VIDEO_CAP_BOTH_OVER_UNDERSCAN = 0x03, }; /** * Video capability data block (VCDB), defined in section 7.5.6. */ struct di_cta_video_cap_block { /* If set to true, YCC quantization range is selectable (via AVI YQ). */ bool selectable_ycc_quantization_range; /* If set to true, RGB quantization range is selectable (via AVI Q). */ bool selectable_rgb_quantization_range; /* Overscan/underscan behavior for PT video formats (if set to unknown, * use the IT/CE behavior) */ enum di_cta_video_cap_over_underscan pt_over_underscan; /* Overscan/underscan behavior for IT video formats */ enum di_cta_video_cap_over_underscan it_over_underscan; /* Overscan/underscan behavior for CE video formats */ enum di_cta_video_cap_over_underscan ce_over_underscan; }; /** * Get the video capabilities from a CTA data block. * * Returns NULL if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO_CAP. */ const struct di_cta_video_cap_block * di_cta_data_block_get_video_cap(const struct di_cta_data_block *block); /** * CTA colorimetry data block, defined in section 7.5.5. */ struct di_cta_colorimetry_block { /* Standard Definition Colorimetry based on IEC 61966-2-4 */ bool xvycc_601; /* High Definition Colorimetry based on IEC 61966-2-4 */ bool xvycc_709; /* Colorimetry based on IEC 61966-2-1/Amendment 1 */ bool sycc_601; /* Colorimetry based on IEC 61966-2-5, Annex A */ bool opycc_601; /* Colorimetry based on IEC 61966-2-5 */ bool oprgb; /* Colorimetry based on Rec. ITU-R BT.2020 Y'cC'bcC'rc */ bool bt2020_cycc; /* Colorimetry based on Rec. ITU-R BT.2020 Y'C'bC'r */ bool bt2020_ycc; /* Colorimetry based on Rec. ITU-R BT.2020 R'G'B' */ bool bt2020_rgb; /* Colorimetry based on SMPTE ST 2113 R'G'B' */ bool st2113_rgb; /* Colorimetry based on Rec. ITU-R BT.2100 ICtCp */ bool ictcp; }; /** * Get the colorimetry data from a CTA data block. * * Returns NULL if the data block tag is not DI_CTA_DATA_BLOCK_COLORIMETRY. */ const struct di_cta_colorimetry_block * di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block); /** * Supported Electro-Optical Transfer Functions for a CTA HDR static metadata * block. */ struct di_cta_hdr_static_metadata_block_eotfs { /* Traditional gamma - SDR luminance range */ bool traditional_sdr; /* Traditional gamma - HDR luminance range */ bool traditional_hdr; /* Perceptual Quantization (PQ) based on SMPTE ST 2084 */ bool pq; /* Hybrid Log-Gamma (HLG) based on Rec. ITU-R BT.2100 */ bool hlg; }; /** * Supported static metadata descriptors for a CTA HDR static metadata block. */ struct di_cta_hdr_static_metadata_block_descriptors { /* Static Metadata Type 1 */ bool type1; }; /** * CTA HDR static metadata block, defined in section 7.5.13. */ struct di_cta_hdr_static_metadata_block { /* Desired content max luminance (cd/m²), zero if unset */ float desired_content_max_luminance; /* Desired content max frame-average luminance (cd/m²), zero if unset */ float desired_content_max_frame_avg_luminance; /* Desired content min luminance (cd/m²), zero if unset */ float desired_content_min_luminance; /* Supported EOFTs */ const struct di_cta_hdr_static_metadata_block_eotfs *eotfs; /* Supported descriptors */ const struct di_cta_hdr_static_metadata_block_descriptors *descriptors; }; /** * Get the HDR static metadata from a CTA data block. * * Returns NULL if the data block tag is not * DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA. */ const struct di_cta_hdr_static_metadata_block * di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block); /** * A Short Video Descriptor (SVD). */ struct di_cta_svd { /* Video Identification Code (VIC) */ uint8_t vic; /* Whether this is a native video format */ bool native; }; /** * Get an array of short video descriptors from a CTA data block. * * Returns NULL if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO. * * The returned array is NULL-terminated. */ const struct di_cta_svd *const * di_cta_data_block_get_svds(const struct di_cta_data_block *block); enum di_cta_vesa_transfer_characteristics_usage { /* White transfer characteristic */ DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_WHITE = 0, /* Red transfer characteristic */ DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_RED = 1, /* Green transfer characteristic */ DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_GREEN = 2, /* Blue transfer characteristic */ DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_BLUE = 3, }; /** * VESA Display Transfer Characteristic Data Block, defined in VESA Display * Transfer Characteristics Data Block Standard Version 1.0 * * Contains 8, 16 or 32 evenly distributed points on the input axis describing * the normalized relative luminance at that input. The first value includes the * relative black level luminance. */ struct di_cta_vesa_transfer_characteristics { enum di_cta_vesa_transfer_characteristics_usage usage; uint8_t points_len; float points[32]; }; /** * Get the Display Transfer Characteristic from a CTA data block. * * Returns NULL if the data block tag is not * DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC. * * Upstream is not aware of any EDID blob containing a Display Transfer * Characteristic data block. * If such a blob is found, please share it with upstream! */ const struct di_cta_vesa_transfer_characteristics * di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block *block); /** * Get a list of EDID detailed timing definitions. * * The returned array is NULL-terminated. */ const struct di_edid_detailed_timing_def *const * di_edid_cta_get_detailed_timing_defs(const struct di_edid_cta *cta); #endif dxvk-0~git20230309.275e645/include/libdisplay-info/displayid.h000066400000000000000000000167511440230200600235000ustar00rootroot00000000000000#ifndef DI_DISPLAYID_H #define DI_DISPLAYID_H /** * libdisplay-info's low-level API for VESA Display Identification Data * (DisplayID). * * The library implements DisplayID version 1.3, available at: * https://vesa.org/vesa-standards/ */ #include #include /** * DisplayID data structure. */ struct di_displayid; /** * Get the DisplayID version. */ int di_displayid_get_version(const struct di_displayid *displayid); /** * Get the DisplayID revision. */ int di_displayid_get_revision(const struct di_displayid *displayid); /** * Product type identifier, defined in section 2.3. */ enum di_displayid_product_type { /* Extension section */ DI_DISPLAYID_PRODUCT_TYPE_EXTENSION = 0x00, /* Test structure or equipment */ DI_DISPLAYID_PRODUCT_TYPE_TEST = 0x01, /* Display panel or other transducer, LCD or PDP module, etc. */ DI_DISPLAYID_PRODUCT_TYPE_DISPLAY_PANEL = 0x02, /* Standalone display device, desktop monitor, TV monitor, etc. */ DI_DISPLAYID_PRODUCT_TYPE_STANDALONE_DISPLAY = 0x03, /* Television receiver */ DI_DISPLAYID_PRODUCT_TYPE_TV_RECEIVER = 0x04, /* Repeater/translator */ DI_DISPLAYID_PRODUCT_TYPE_REPEATER = 0x05, /* Direct drive monitor */ DI_DISPLAYID_PRODUCT_TYPE_DIRECT_DRIVE = 0x06, }; /** * Get the DisplayID product type. */ enum di_displayid_product_type di_displayid_get_product_type(const struct di_displayid *displayid); /** * DisplayID data block tag. */ enum di_displayid_data_block_tag { /*Product Identification Data Block */ DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID = 0x00, /* Display Parameters Data Block */ DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS = 0x01, /* Color Characteristics Data Block */ DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT = 0x02, /* Video Timing Modes Type I - Detailed Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING = 0x03, /* Video Timing Modes Type II - Detailed Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING = 0x04, /* Video Timing Modes Type III - Short Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING = 0x05, /* Video Timing Modes Type IV - DMT Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_IV_TIMING = 0x06, /* Supported Timing Modes - VESA DMT Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_VESA_TIMING = 0x07, /* Supported Timing Modes - CTA-861 Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_CEA_TIMING = 0x08, /* Video Timing Range Data Block */ DI_DISPLAYID_DATA_BLOCK_TIMING_RANGE_LIMITS = 0x09, /* Product Serial Number Data Block */ DI_DISPLAYID_DATA_BLOCK_PRODUCT_SERIAL = 0x0A, /* General-purpose ASCII String Data Block */ DI_DISPLAYID_DATA_BLOCK_ASCII_STRING = 0x0B, /* Display Device Data Data Block */ DI_DISPLAYID_DATA_BLOCK_DISPLAY_DEVICE_DATA = 0x0C, /* Interface Power Sequencing Data Block */ DI_DISPLAYID_DATA_BLOCK_INTERFACE_POWER_SEQ = 0x0D, /* Transfer Characteristics Data Block */ DI_DISPLAYID_DATA_BLOCK_TRANSFER_CHARACT = 0x0E, /* Display Interface Data Block */ DI_DISPLAYID_DATA_BLOCK_DISPLAY_INTERFACE = 0x0F, /* Stereo Display Interface Data Block */ DI_DISPLAYID_DATA_BLOCK_STEREO_DISPLAY_INTERFACE = 0x10, /* Video Timing Modes Type V - Short Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_V_TIMING = 0x11, /* Tiled Display Topology Data Block */ DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO = 0x12, /* Video Timing Modes Type VI - Detailed Timings Data Block */ DI_DISPLAYID_DATA_BLOCK_TYPE_VI_TIMING = 0x13, }; /** * A DisplayID data block. */ struct di_displayid_data_block; /** * Get a DisplayID data block tag. */ enum di_displayid_data_block_tag di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block); /** * Display parameters feature support flags, defined in section 4.2.3. */ struct di_displayid_display_params_features { /* Audio support on video interface */ bool audio; /* Audio inputs are provided separately from the video interface */ bool separate_audio_inputs; /* Audio information received via the video interface will automatically * override any other audio input channels provided */ bool audio_input_override; /* Display supports the VESA Display Power Management (DPM) standard */ bool power_management; /* Display is capable of only a single fixed timing */ bool fixed_timing; /* Display is capable of supporting timings at only a single fixed pixel * format */ bool fixed_pixel_format; /* Display supports ACP, ISRC1 or ISRC2 packets */ bool ai; /* Display by default will de-interlace any interlaced video input */ bool deinterlacing; }; /** * Display parameters data block, defined in section 4.2. */ struct di_displayid_display_params { /* Image size in millimeters accurate to the thenths place, zero if unset */ float horiz_image_mm, vert_image_mm; /* Native format size in pixels, zero if unset */ int32_t horiz_pixels, vert_pixels; /* Feature flags */ const struct di_displayid_display_params_features *features; /* Transfer characteristic gamma, zero if unset */ float gamma; /* Aspect ratio (long axis divided by short axis) */ float aspect_ratio; /* Color bit depth (dynamic range) */ int32_t bits_per_color_overall, bits_per_color_native; }; /** * Get display parameters from a DisplayID data block. * * Returns NULL if the data block tag isn't * DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS. */ const struct di_displayid_display_params * di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block); enum di_displayid_type_i_timing_stereo_3d { /* This timing is always displayed monoscopic (no stereo) */ DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_NEVER = 0x00, /* This timing is always displayed in stereo */ DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_ALWAYS = 0x01, /* This timing is displayed in mono or stereo depending on a user action * (wearing the stereo glasses, etc.) */ DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_USER = 0x02, }; enum di_displayid_type_i_timing_aspect_ratio { DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_1_1 = 0x00, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_5_4 = 0x01, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_4_3 = 0x02, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_15_9 = 0x03, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_9 = 0x04, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_16_10 = 0x05, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_64_27 = 0x06, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_256_135 = 0x07, DI_DISPLAYID_TYPE_I_TIMING_ASPECT_RATIO_UNDEFINED = 0x08, }; enum di_displayid_type_i_timing_sync_polarity { DI_DISPLAYID_TYPE_I_TIMING_SYNC_NEGATIVE = 0x00, DI_DISPLAYID_TYPE_I_TIMING_SYNC_POSITIVE = 0x01, }; /** * Type I timing, defined in section 4.4.1. */ struct di_displayid_type_i_timing { double pixel_clock_mhz; /* mega-hertz */ bool preferred; enum di_displayid_type_i_timing_stereo_3d stereo_3d; bool interlaced; enum di_displayid_type_i_timing_aspect_ratio aspect_ratio; int32_t horiz_active, vert_active; int32_t horiz_blank, vert_blank; int32_t horiz_offset, vert_offset; int32_t horiz_sync_width, vert_sync_width; enum di_displayid_type_i_timing_sync_polarity horiz_sync_polarity, vert_sync_polarity; }; /** * Get type I timings from a DisplayID data block. * * The returned array is NULL-terminated. * * Returns NULL if the data block tag isn't * DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING. */ const struct di_displayid_type_i_timing *const * di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *data_block); /** * Get DisplayID data blocks. * * The returned array is NULL-terminated. */ const struct di_displayid_data_block *const * di_displayid_get_data_blocks(const struct di_displayid *displayid); #endif dxvk-0~git20230309.275e645/include/libdisplay-info/dmt.h000066400000000000000000000017111440230200600222700ustar00rootroot00000000000000#ifndef DI_DMT_H #define DI_DMT_H /** * libdisplay-info's low-level API for VESA Display Monitor Timing (DMT). * * The library implements VESA DMT version 1.0 revision 13. */ #include /** * A DMT timing. */ struct di_dmt_timing { /* DMT ID */ uint8_t dmt_id; /* EDID standard timing 2-byte code, zero if unset */ uint16_t edid_std_id; /* CVT 3-byte code, zero if unset */ uint32_t cvt_id; /* Addressable pixels */ int32_t horiz_video, vert_video; /* Field Refresh Rate in Hz */ float refresh_rate_hz; /* Pixel clock in Hz */ int32_t pixel_clock_hz; /* Horizontal/Vertical Blanking in pixels/lines */ int32_t horiz_blank, vert_blank; /* Horizontal/Vertical Front Porch in pixels/lines */ int32_t horiz_front_porch, vert_front_porch; /* Horizontal/Vertical Sync Pulse Width in pixels/lines */ int32_t horiz_sync_pulse, vert_sync_pulse; /* Horizontal/Vertical Border in pixels/lines */ int32_t horiz_border, vert_border; }; #endif dxvk-0~git20230309.275e645/include/libdisplay-info/edid.h000066400000000000000000000541511440230200600224170ustar00rootroot00000000000000#ifndef DI_EDID_H #define DI_EDID_H /** * libdisplay-info's low-level API for Extended Display Identification * Data (EDID). * * EDID 1.4 is defined in VESA Enhanced Extended Display Identification Data * Standard release A revision 2. */ #include #include #include /** * EDID data structure. */ struct di_edid; /** * Get the EDID version. */ int di_edid_get_version(const struct di_edid *edid); /** * Get the EDID revision. */ int di_edid_get_revision(const struct di_edid *edid); /** * EDID vendor & product identification. */ struct di_edid_vendor_product { char manufacturer[3]; uint16_t product; uint32_t serial; /* zero if unset */ /* These fields are zero if unset */ int manufacture_week; int manufacture_year; int model_year; }; const struct di_edid_vendor_product * di_edid_get_vendor_product(const struct di_edid *edid); /** * EDID analog signal level standard. */ enum di_edid_video_input_analog_signal_level_std { /* 0.700 : 0.300 : 1.000 V p-p */ DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_0 = 0x00, /* 0.714 : 0.286 : 1.000 V p-p */ DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_1 = 0x01, /* 1.000 : 0.400 : 1.400 V p-p */ DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_2 = 0x02, /* 0.700 : 0.000 : 0.700 V p-p */ DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_3 = 0x03, }; /** * EDID analog video setup. */ enum di_edid_video_input_analog_video_setup { /* Blank level equals black level */ DI_EDID_VIDEO_INPUT_ANALOG_BLANK_LEVEL_EQ_BLACK = 0, /* Blank-to-black setup or pedestal */ DI_EDID_VIDEO_INPUT_ANALOG_BLANK_TO_BLACK_SETUP_PEDESTAL = 1, }; /** * EDID analog video input basic information, defined in section 3.6.1. */ struct di_edid_video_input_analog { enum di_edid_video_input_analog_signal_level_std signal_level_std; enum di_edid_video_input_analog_video_setup video_setup; /* Separate Sync H & V Signals are supported */ bool sync_separate; /* Composite Sync Signal on Horizontal is supported */ bool sync_composite; /* Composite Sync Signal on Green Video is supported */ bool sync_on_green; /* Serration on the Vertical Sync is supported */ bool sync_serrations; }; /** * Get the analog video input basic information. * * Returns NULL if this isn't an analog display. */ const struct di_edid_video_input_analog * di_edid_get_video_input_analog(const struct di_edid *edid); /** * Digital video input interface standard. */ enum di_edid_video_input_digital_interface { DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED = 0x00, DI_EDID_VIDEO_INPUT_DIGITAL_DVI = 0x01, DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_A = 0x02, DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_B = 0x03, DI_EDID_VIDEO_INPUT_DIGITAL_MDDI = 0x04, DI_EDID_VIDEO_INPUT_DIGITAL_DISPLAYPORT = 0x05, }; /** * EDID digital video input basic information, defined in section 3.6.1. */ struct di_edid_video_input_digital { /* EDID 1.2 and 1.3 */ bool dfp1; /* Compatible with VESA DFP 1.x TDMS CRGB */ /* EDID 1.4 and later */ int color_bit_depth; /* zero if undefined */ enum di_edid_video_input_digital_interface interface; }; /** * Get the digital video input basic information. * * Returns NULL if this isn't a digital display. */ const struct di_edid_video_input_digital * di_edid_get_video_input_digital(const struct di_edid *edid); struct di_edid_screen_size { /* Physical size in centimeters, zero if unset */ int width_cm, height_cm; /* Aspect ratio rounded to the hundredth decimal place, zero if unset. */ float landscape_aspect_ratio, portait_aspect_ratio; }; /** * Get the screen size. */ const struct di_edid_screen_size * di_edid_get_screen_size(const struct di_edid *edid); /** * Get the display transfer characteristics from the basic EDID parameters, also * known as "gamma". * * Returns 0 if unset (ie, stored in an extension block). */ float di_edid_get_basic_gamma(const struct di_edid *edid); /** * Supported legacy Display Power Management Signaling (DPMS) states, defined in * section 3.6.4. * * Display Power Management (DPM) compliant displays only support "off". */ struct di_edid_dpms { bool standby; bool suspend; bool off; }; /** * Get the set of supported legacy DPMS states. */ const struct di_edid_dpms * di_edid_get_dpms(const struct di_edid *edid); /** * Display color type. */ enum di_edid_display_color_type { /* Monochrome or grayscale display */ DI_EDID_DISPLAY_COLOR_MONOCHROME = 0x00, /* RGB color display */ DI_EDID_DISPLAY_COLOR_RGB = 0x01, /* Non-RGB color display */ DI_EDID_DISPLAY_COLOR_NON_RGB = 0x02, /* Undefined */ DI_EDID_DISPLAY_COLOR_UNDEFINED = 0x03, }; /** * Get the display color type. * * For digital displays using EDID 1.4 and later, DI_EDID_DISPLAY_COLOR_UNDEFINED * is always returned. */ enum di_edid_display_color_type di_edid_get_display_color_type(const struct di_edid *edid); /** * Basic color encoding formats, defined in section 3.6.4. */ struct di_edid_color_encoding_formats { bool rgb444; /* RGB 4:4:4 */ bool ycrcb444; /* YCrCb 4:4:4 */ bool ycrcb422; /* YCrCb 4:2:2 */ }; /** * Get the set of supported color encoding formats. * * Returns NULL if the display is analog or if the color encoding formats are * not specified. */ const struct di_edid_color_encoding_formats * di_edid_get_color_encoding_formats(const struct di_edid *edid); /** * Miscellaneous basic features, defined in section 3.6.4. * * Note, the enum values don't match the specification. */ struct di_edid_misc_features { /** * First detailed timing is the preferred timing. * * Always set for EDID 1.4 and later. */ bool has_preferred_timing; /** * GTF using the default parameters is supported. * * Never set for EDID 1.4 and later. */ bool default_gtf; /** * sRGB standard default color space is primary color space. */ bool srgb_is_primary; /** * Preferred timing mode includes native pixel format and rate. * * Never set for EDID 1.3 and earlier. */ bool preferred_timing_is_native; /** * GTF or CVT generated timings within the display's range limits are * accepted. * * Never set for EDID 1.3 and earlier. */ bool continuous_freq; }; /** * Get the set of miscellaneous basic features. */ const struct di_edid_misc_features * di_edid_get_misc_features(const struct di_edid *edid); /** * EDID display chromaticity coordinates, defined in section 3.7. * * The values are accurate to the thousandth place. The red, green and blue * values are zero for monochrome displays. */ struct di_edid_chromaticity_coords { float red_x, red_y; float green_x, green_y; float blue_x, blue_y; float white_x, white_y; }; /** * Get chromaticity coordinates. */ const struct di_edid_chromaticity_coords * di_edid_get_chromaticity_coords(const struct di_edid *edid); /** * Established timings I and II, defined in section 3.8. */ struct di_edid_established_timings_i_ii { /* Established timings I */ bool has_720x400_70hz; /* 720 x 400 @ 70Hz (IBM, VGA) */ bool has_720x400_88hz; /* 720 x 400 @ 88Hz (IBM, XGA2) */ bool has_640x480_60hz; /* 640 x 480 @ 60Hz (IBM, VGA) */ bool has_640x480_67hz; /* 640 x 480 @ 67Hz (Apple, Mac II) */ bool has_640x480_72hz; /* 640 x 480 @ 72Hz (VESA) */ bool has_640x480_75hz; /* 640 x 480 @ 75Hz (VESA) */ bool has_800x600_56hz; /* 800 x 600 @ 56Hz (VESA) */ bool has_800x600_60hz; /* 800 x 600 @ 60Hz (VESA) */ /* Established timings II */ bool has_800x600_72hz; /* 800 x 600 @ 72Hz (VESA) */ bool has_800x600_75hz; /* 800 x 600 @ 75Hz (VESA) */ bool has_832x624_75hz; /* 832 x 624 @ 75Hz (Apple, Mac II) */ bool has_1024x768_87hz_interlaced; /* 1024 x 768 @ 87Hz interlaced (IBM) */ bool has_1024x768_60hz; /* 1024 x 768 @ 60Hz (VESA) */ bool has_1024x768_70hz; /* 1024 x 768 @ 70Hz (VESA) */ bool has_1024x768_75hz; /* 1024 x 768 @ 75Hz (VESA) */ bool has_1280x1024_75hz; /* 1280 x 1024 @ 75Hz (VESA) */ bool has_1152x870_75hz; /* 1152 x 870 @ 75Hz (Apple, Mac II) */ }; /** * Get established timings I and II. */ const struct di_edid_established_timings_i_ii * di_edid_get_established_timings_i_ii(const struct di_edid *edid); /** * Aspect ratio for an EDID standard timing. */ enum di_edid_standard_timing_aspect_ratio { DI_EDID_STANDARD_TIMING_16_10 = 0, /* 16:10 */ DI_EDID_STANDARD_TIMING_4_3 = 1, /* 4:3 */ DI_EDID_STANDARD_TIMING_5_4 = 2, /* 5:4 */ DI_EDID_STANDARD_TIMING_16_9 = 3, /* 16:9 */ }; /** * EDID standard timing, defined in section 3.9. */ struct di_edid_standard_timing { /* Horizontal addressable pixels */ int32_t horiz_video; /* Aspect ratio */ enum di_edid_standard_timing_aspect_ratio aspect_ratio; /* Field Refresh Rate in Hz */ int32_t refresh_rate_hz; }; /** * Get the vertical addressable line count of an EDID standard timing. */ int32_t di_edid_standard_timing_get_vert_video(const struct di_edid_standard_timing *t); /* See */ struct di_dmt_timing; /** * Get the VESA Display Monitor Timing (DMT), if any. * * NULL is returned if the standard timing doesn't have a DMT. */ const struct di_dmt_timing * di_edid_standard_timing_get_dmt(const struct di_edid_standard_timing *t); /** * Get a list of EDID standard timings. * * The returned array is NULL-terminated. */ const struct di_edid_standard_timing *const * di_edid_get_standard_timings(const struct di_edid *edid); /** * Stereo viewing support. */ enum di_edid_detailed_timing_def_stereo { /* Normal Display – No Stereo */ DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE, /* Field sequential stereo, right image when stereo sync signal = 1 */ DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_RIGHT, /* Field sequential stereo, left image when stereo sync signal = 1 */ DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_LEFT, /* 2-way interleaved stereo, right image on even lines */ DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_RIGHT, /* 2-way interleaved stereo, left image on even lines */ DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_LEFT, /* 4-way interleaved stereo */ DI_EDID_DETAILED_TIMING_DEF_STEREO_4_WAY_INTERLEAVED, /* Side-by-Side interleaved stereo */ DI_EDID_DETAILED_TIMING_DEF_STEREO_SIDE_BY_SIDE_INTERLEAVED, }; /** * Signal definitions for EDID detailed timings, defined in notes for table 3.22. */ enum di_edid_detailed_timing_def_signal_type { /* Analog composite */ DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE = 0x00, /* Bipolar analog composite */ DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE = 0x01, /* Digital composite */ DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE = 0x02, /* Digital separate */ DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE = 0x03, }; /** * Digital separate sync polarity for EDID detailed timings. */ enum di_edid_detailed_timing_def_sync_polarity { DI_EDID_DETAILED_TIMING_DEF_SYNC_NEGATIVE = 0, DI_EDID_DETAILED_TIMING_DEF_SYNC_POSITIVE = 1, }; /** * Flags for ANALOG_COMPOSITE signals */ struct di_edid_detailed_timing_analog_composite { /* Sync with serrations (H-sync during V-sync) */ bool sync_serrations; /* Sync on green signal only (as opposed to all three * RGB video signals) */ bool sync_on_green; }; /** * Flags for BIPOLAR_ANALOG_COMPOSITE signals */ struct di_edid_detailed_timing_bipolar_analog_composite { /* Sync with serrations (H-sync during V-sync) */ bool sync_serrations; /* Sync on green signal only (as opposed to all three * RGB video signals) */ bool sync_on_green; }; /** * Flags for DIGITAL_COMPOSITE signals */ struct di_edid_detailed_timing_digital_composite { /* Sync with serrations (H-sync during V-sync) */ bool sync_serrations; /* Horizontal polarity (outside of V-sync) */ enum di_edid_detailed_timing_def_sync_polarity sync_horiz_polarity; }; /** * Flags for DIGITAL_SEPARATE signals */ struct di_edid_detailed_timing_digital_separate { /* Vertical polarity */ enum di_edid_detailed_timing_def_sync_polarity sync_vert_polarity; /* Horizontal polarity (outside of V-sync) */ enum di_edid_detailed_timing_def_sync_polarity sync_horiz_polarity; }; /** * EDID detailed timing definition, defined in section 3.10.2. */ struct di_edid_detailed_timing_def { /* Pixel clock */ int32_t pixel_clock_hz; /* Horizontal/Vertical Addressable Video in pixels/lines */ int32_t horiz_video, vert_video; /* Horizontal/Vertical Blanking in pixels/lines */ int32_t horiz_blank, vert_blank; /* Horizontal/Vertical Front Porch in pixels/lines */ int32_t horiz_front_porch, vert_front_porch; /* Horizontal/Vertical Sync Pulse Width in pixels/lines */ int32_t horiz_sync_pulse, vert_sync_pulse; /* Horizontal/Vertical Addressable Video Image Size in mm, zero if unset */ int32_t horiz_image_mm, vert_image_mm; /* Horizontal/Vertical Border in pixels/lines */ int32_t horiz_border, vert_border; /* Interlaced signal */ bool interlaced; /* Stereo Viewing Support */ enum di_edid_detailed_timing_def_stereo stereo; /* Signal type */ enum di_edid_detailed_timing_def_signal_type signal_type; /* Flags for ANALOG_COMPOSITE signals, NULL otherwise */ const struct di_edid_detailed_timing_analog_composite *analog_composite; /* Flags for BIPOLAR_ANALOG_COMPOSITE signals, NULL otherwise */ const struct di_edid_detailed_timing_bipolar_analog_composite *bipolar_analog_composite; /* Flags for DIGITAL_COMPOSITE signals, NULL otherwise */ const struct di_edid_detailed_timing_digital_composite *digital_composite; /* Flags for DIGITAL_SEPARATE signals, NULL otherwise */ const struct di_edid_detailed_timing_digital_separate *digital_separate; }; /** * Get a list of EDID detailed timing definitions. * * The returned array is NULL-terminated. */ const struct di_edid_detailed_timing_def *const * di_edid_get_detailed_timing_defs(const struct di_edid *edid); /** * EDID display descriptor. */ struct di_edid_display_descriptor; /** * Get a list of EDID display descriptors. * * The returned array is NULL-terminated. */ const struct di_edid_display_descriptor *const * di_edid_get_display_descriptors(const struct di_edid *edid); /** * EDID display descriptor tag, defined in section 3.10.3. */ enum di_edid_display_descriptor_tag { /* Display Product Serial Number */ DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL = 0xFF, /* Alphanumeric Data String (ASCII) */ DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING = 0xFE, /* Display Range Limits */ DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS = 0xFD, /* Display Product Name */ DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME = 0xFC, /* Color Point Data */ DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT = 0xFB, /* Standard Timing Identifications */ DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS = 0xFA, /* Display Color Management (DCM) Data */ DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA = 0xF9, /* CVT 3 Byte Timing Codes */ DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES = 0xF8, /* Established Timings III */ DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III = 0xF7, /* Dummy Descriptor */ DI_EDID_DISPLAY_DESCRIPTOR_DUMMY = 0x10, }; /** * Get the tag of an EDID display descriptor. */ enum di_edid_display_descriptor_tag di_edid_display_descriptor_get_tag(const struct di_edid_display_descriptor *desc); /** * Get the contents of a product serial number, a data string, or a product name * display descriptor. * * Returns NULL if the display descriptor tag isn't either * DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL_NUMBER, * DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING or * DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME. */ const char * di_edid_display_descriptor_get_string(const struct di_edid_display_descriptor *desc); /** * EDID display range limits type. * * The values do not match the EDID specification. * * The CVT entry was introduced in EDID 1.4. */ enum di_edid_display_range_limits_type { /* Range Limits Only - no additional timing information is provided */ DI_EDID_DISPLAY_RANGE_LIMITS_BARE, /* Default GTF supported */ DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF, /* Secondary GTF supported */ DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF, /* CVT supported */ DI_EDID_DISPLAY_RANGE_LIMITS_CVT, }; struct di_edid_display_range_limits_secondary_gtf { /* Start break frequency in Hz */ int start_freq_hz; /* C, M, K, J parameters */ float c, m, k, j; }; enum di_edid_cvt_aspect_ratio { DI_EDID_CVT_ASPECT_RATIO_4_3 = 1 << 7, DI_EDID_CVT_ASPECT_RATIO_16_9 = 1 << 6, DI_EDID_CVT_ASPECT_RATIO_16_10 = 1 << 5, DI_EDID_CVT_ASPECT_RATIO_5_4 = 1 << 4, DI_EDID_CVT_ASPECT_RATIO_15_9 = 1 << 3, }; enum di_edid_cvt_scaling { DI_EDID_CVT_SCALING_HORIZ_SHRINK = 1 << 7, DI_EDID_CVT_SCALING_HORIZ_STRETCH = 1 << 6, DI_EDID_CVT_SCALING_VERT_SHRINK = 1 << 5, DI_EDID_CVT_SCALING_VERT_STRETCH = 1 << 4, }; struct di_edid_display_range_limits_cvt { int32_t version, revision; /* Maximum active pixels per line, zero for no limit */ int32_t max_horiz_px; /* Supported aspect ratio, bitfield of enum di_edid_cvt_aspect_ratio */ uint32_t supported_aspect_ratio; /* Preferred aspect ratio */ enum di_edid_cvt_aspect_ratio preferred_aspect_ratio; /* Whether standard CVT blanking is supported */ bool standard_blanking; /* Whether reduced CVT blanking is supported */ bool reduced_blanking; /* Supported types of display scaling, bitfield of * enum di_edid_cvt_scaling */ uint32_t supported_scaling; /* Preferred vertical refresh rate, in Hz */ int32_t preferred_vert_refresh_hz; }; /** * EDID display range limits, defined in section 3.10.3.3.1. */ struct di_edid_display_range_limits { /* Vertical rate limits in Hz, from 1 Hz to 510 Hz */ int32_t min_vert_rate_hz, max_vert_rate_hz; /* Horizontal rate limits in Hz, from 1 KHz to 510 KHz, rounded to the * nearest multiple of 1 KHz */ int32_t min_horiz_rate_hz, max_horiz_rate_hz; /* Maximum pixel clock in Hz, zero if unset, rounded to the nearest * multiple of 0.25 MHz if CVT, otherwise to the nearest multiple of * 10 MHz */ int32_t max_pixel_clock_hz; enum di_edid_display_range_limits_type type; /* For SECONDARY_GTF limits, NULL otherwise */ const struct di_edid_display_range_limits_secondary_gtf *secondary_gtf; /* For CVT limits, NULL otherwise */ const struct di_edid_display_range_limits_cvt *cvt; }; /** * Get the contents of a display range limits descriptor. * * Returns NULL if the display descriptor tag isn't * DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS. */ const struct di_edid_display_range_limits * di_edid_display_descriptor_get_range_limits(const struct di_edid_display_descriptor *desc); /** * Get a standard timing list from an EDID display descriptor. * * The returned array is NULL-terminated. * * Returns NULL if the display descriptor tag isn't * DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS. */ const struct di_edid_standard_timing *const * di_edid_display_descriptor_get_standard_timings(const struct di_edid_display_descriptor *desc); /** * EDID Color Points, defined in section 3.10.3.5. */ struct di_edid_color_point { /* White point index number */ int index; /* The white chromaticity values, accurate to the thousandth place */ float white_x, white_y; /* Gamma, zero if unset (ie, stored in an extension block) */ float gamma; }; /** * Get a color point list from an EDID display descriptor. * * The returned array is NULL-terminated. * * Returns NULL if the display descriptor tag isn't * DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT. * * Upstream is not aware of any EDID blob containing Color Point Descriptors. * If such a blob is found, please share it with upstream! */ const struct di_edid_color_point *const * di_edid_display_descriptor_get_color_points(const struct di_edid_display_descriptor *desc); /** * Get a list of established timings III from an EDID display descriptor. * * The returned array is NULL-terminated. * * Returns NULL if the display descriptor tag isn't * DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III. */ const struct di_dmt_timing *const * di_edid_display_descriptor_get_established_timings_iii(const struct di_edid_display_descriptor *desc); /** * EDID display Color Management Data, defined in section 3.10.3.7 * * Contains the coefficients for the function `L = a₃ × v³ + a₂ × v²` * describing the luminance response L to some voltage v [0, 0.7] for each color * channel. * * For more information see VESA DCM Standard, Version 1; January 6, 2003 */ struct di_edid_color_management_data { int version; /* red polynomial coefficient a3 */ float red_a3; /* red polynomial coefficient a2 */ float red_a2; /* green polynomial coefficient a3 */ float green_a3; /* green polynomial coefficient a2 */ float green_a2; /* blue polynomial coefficient a3 */ float blue_a3; /* blue polynomial coefficient a2 */ float blue_a2; }; /** * Get the contents of a Display Color Management (DCM) Data descriptor. * * Returns NULL if the display descriptor tag isn't * DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA. * * Upstream is not aware of any EDID blob containing DCM Data descriptors. * If such a blob is found, please share it with upstream! */ const struct di_edid_color_management_data * di_edid_display_descriptor_get_color_management_data(const struct di_edid_display_descriptor *desc); /** * Get a list of EDID extensions. * * The returned array is NULL-terminated. */ const struct di_edid_ext *const * di_edid_get_extensions(const struct di_edid *edid); /** * EDID extension block tags, defined in section 2.2.4. */ enum di_edid_ext_tag { /* CEA 861 Series Extension */ DI_EDID_EXT_CEA = 0x02, /* Video Timing Block Extension */ DI_EDID_EXT_VTB = 0x10, /* Display Information Extension */ DI_EDID_EXT_DI = 0x40, /* Localized String Extension */ DI_EDID_EXT_LS = 0x50, /* Digital Packet Video Link Extension */ DI_EDID_EXT_DPVL = 0x60, /* Extension Block Map */ DI_EDID_EXT_BLOCK_MAP = 0xF0, /* Extension defined by the display manufacturer */ DI_EDID_EXT_VENDOR = 0xFF, /* DisplayID Extension */ DI_EDID_EXT_DISPLAYID = 0x70, }; /** * EDID extension block. */ struct di_edid_ext; /** * Get the tag of an EDID extension block. */ enum di_edid_ext_tag di_edid_ext_get_tag(const struct di_edid_ext *ext); /* See */ struct di_edid_cta; /** * Get a CTA-861 extension block. * * Returns NULL if the extension block tag is not DI_EDID_EXT_CEA. */ const struct di_edid_cta * di_edid_ext_get_cta(const struct di_edid_ext *ext); /* See */ struct di_displayid; /** * Get a DisplayID extension block. * * Returns NULL if the extension block tag is not DI_EDID_EXT_DISPLAYID. */ const struct di_displayid * di_edid_ext_get_displayid(const struct di_edid_ext *ext); #endif dxvk-0~git20230309.275e645/include/libdisplay-info/gtf.h000066400000000000000000000032431440230200600222660ustar00rootroot00000000000000#ifndef DI_GTF_H #define DI_GTF_H #include /** * Low-level API for Generalized Timing Formula Standard version 1.1. */ /** * Type of frequency parameter used in di_gtf_options.ip_freq_rqd. */ enum di_gtf_ip_param { /* Vertical frame frequency (Hz) */ DI_GTF_IP_PARAM_V_FRAME_RATE, /* Horizontal frequency (kHz) */ DI_GTF_IP_PARAM_H_FREQ, /* Pixel clock rate (MHz) */ DI_GTF_IP_PARAM_H_PIXELS, }; /** * Input options for GTF. */ struct di_gtf_options { /* Number of active image pixels displayed on a line, not including any * margin */ int h_pixels; /* Number of vertical lines in the displayed image */ int v_lines; /* Whether margins are required */ bool margins_rqd; /* Indicates which frequency parameter is specified in ip_freq_rqd */ enum di_gtf_ip_param ip_param; /* Vertical frame frequency (in Hz), horizontal frequency (in kHz) or * pixel clock rate (in MHz) */ double ip_freq_rqd; /* Whether interlaced is required */ bool int_rqd; /* Blanking formula gradient */ double m; /* Blanking formula offset */ double c; /* Blanking formula scaling factor */ double k; /* Blanking formula scaling factor weighting */ double j; }; #define DI_GTF_DEFAULT_M 600.0 #define DI_GTF_DEFAULT_C 40.0 #define DI_GTF_DEFAULT_K 128.0 #define DI_GTF_DEFAULT_J 20.0 /** * Output timing data for GTF. */ struct di_gtf_timing { int h_pixels, v_lines; int h_sync, v_sync; int h_front_porch, h_back_porch; int v_front_porch, v_back_porch; int h_border, v_border; double pixel_freq_mhz; /* in mega-hertz */ }; /** * Compute a timing via the GTF formula. */ void di_gtf_compute(struct di_gtf_timing *t, const struct di_gtf_options *options); #endif dxvk-0~git20230309.275e645/include/libdisplay-info/info.h000066400000000000000000000054461440230200600224500ustar00rootroot00000000000000#ifndef DI_INFO_H #define DI_INFO_H #include /** * libdisplay-info's high-level API. */ /** * Information about a display device. * * This includes at least one EDID or DisplayID blob. * * Use di_info_parse_edid() to create a struct di_info from an EDID blob. * DisplayID blobs are not yet supported. */ struct di_info; /** * Parse an EDID blob. * * Callers do not need to keep the provided data pointer valid after calling * this function. Callers should destroy the returned pointer via * di_info_destroy(). */ struct di_info * di_info_parse_edid(const void *data, size_t size); /** * Destroy a display device information structure. */ void di_info_destroy(struct di_info *info); /** * Returns the EDID the display device information was constructed with. * * The returned struct di_edid can be used to query low-level EDID information, * see . Users should prefer the high-level API if * possible. * * NULL is returned if the struct di_info doesn't contain an EDID. The returned * struct di_edid is valid until di_info_destroy(). */ const struct di_edid * di_info_get_edid(const struct di_info *info); /** * Get the failure messages for this blob. * * NULL is returned if the blob conforms to the relevant specifications. */ const char * di_info_get_failure_msg(const struct di_info *info); /** * Get the make of the display device. * * This is the manufacturer name, either company name or PNP ID. * This string is informational and not meant to be used in programmatic * decisions, configuration keys, etc. * * The string is in UTF-8 and may contain any characters except ASCII control * codes. * * The caller is responsible for free'ing the returned string. * NULL is returned if the information is not available. */ char * di_info_get_make(const struct di_info *info); /** * Get the model of the display device. * * This is the product name/model string or product number. * This string is informational and not meant to be used in programmatic * decisions, configuration keys, etc. * * The string is in UTF-8 and may contain any characters except ASCII control * codes. * * The caller is responsible for free'ing the returned string. * NULL is returned if the information is not available. */ char * di_info_get_model(const struct di_info *info); /** * Get the serial of the display device. * * This is the product serial string or the serial number. * This string is informational and not meant to be used in programmatic * decisions, configuration keys, etc. * * The string is in UTF-8 and may contain any characters except ASCII control * codes. * * The caller is responsible for free'ing the returned string. * NULL is returned if the information is not available. */ char * di_info_get_serial(const struct di_info *info); #endif dxvk-0~git20230309.275e645/include/log.h000066400000000000000000000004551440230200600172040ustar00rootroot00000000000000#ifndef LOG_H #define LOG_H /** * Private logging utilities. */ #include #include #include struct di_logger { FILE *f; const char *section; bool initialized; }; void _di_logger_va_add_failure(struct di_logger *logger, const char fmt[], va_list args); #endif dxvk-0~git20230309.275e645/include/memory-stream.h000066400000000000000000000006771440230200600212320ustar00rootroot00000000000000#ifndef MEMORY_STREAM_H #define MEMORY_STREAM_H /** * Private header for the high-level API. */ #include #include #include #ifdef _WIN32 #define MEMSTREAM_MAX_PATH 260 #endif struct memory_stream { FILE *fp; char *str; size_t str_len; #ifdef _WIN32 char temp[MEMSTREAM_MAX_PATH]; #endif }; bool memory_stream_open(struct memory_stream *m); char * memory_stream_close(struct memory_stream *m); #endif dxvk-0~git20230309.275e645/info.c000066400000000000000000000073021440230200600157240ustar00rootroot00000000000000#include #include #include #include #include #include "edid.h" #include "info.h" #include "log.h" #include "memory-stream.h" /* Generated file pnp-id-table.c: */ const char * pnp_id_table(const char *key); struct di_info * di_info_parse_edid(const void *data, size_t size) { struct di_edid *edid; struct di_info *info; struct memory_stream failure_msg; if (!memory_stream_open(&failure_msg)) return NULL; edid = _di_edid_parse(data, size, failure_msg.fp); if (!edid) goto err_failure_msg_file; info = calloc(1, sizeof(*info)); if (!info) goto err_edid; info->edid = edid; if (fflush(failure_msg.fp) != 0) goto err_info; info->failure_msg = memory_stream_close(&failure_msg); return info; err_info: free(info); err_edid: _di_edid_destroy(edid); err_failure_msg_file: memory_stream_close(&failure_msg); return NULL; } void di_info_destroy(struct di_info *info) { _di_edid_destroy(info->edid); free(info->failure_msg); free(info); } const struct di_edid * di_info_get_edid(const struct di_info *info) { return info->edid; } const char * di_info_get_failure_msg(const struct di_info *info) { return info->failure_msg; } static void encode_ascii_byte(FILE *out, char ch) { uint8_t c = (uint8_t)ch; /* * Replace ASCII control codes and non-7-bit codes * with an escape string. The result is guaranteed to be valid * UTF-8. */ if (c < 0x20 || c >= 0x7f) fprintf(out, "\\x%02x", c); else fputc(c, out); } static void encode_ascii_string(FILE *out, const char *str) { size_t len = strlen(str); size_t i; for (i = 0; i < len; i++) encode_ascii_byte(out, str[i]); } char * di_info_get_make(const struct di_info *info) { const struct di_edid_vendor_product *evp; char pnp_id[(sizeof(evp->manufacturer)) + 1] = { 0, }; const char *manuf; struct memory_stream m; if (!info->edid) return NULL; if (!memory_stream_open(&m)) return NULL; evp = di_edid_get_vendor_product(info->edid); memcpy(pnp_id, evp->manufacturer, sizeof(evp->manufacturer)); manuf = pnp_id_table(pnp_id); if (manuf) { encode_ascii_string(m.fp, manuf); return memory_stream_close(&m); } fputs("PNP(", m.fp); encode_ascii_string(m.fp, pnp_id); fputs(")", m.fp); return memory_stream_close(&m); } char * di_info_get_model(const struct di_info *info) { const struct di_edid_vendor_product *evp; const struct di_edid_display_descriptor *const *desc; struct memory_stream m; size_t i; if (!info->edid) return NULL; if (!memory_stream_open(&m)) return NULL; desc = di_edid_get_display_descriptors(info->edid); for (i = 0; desc[i]; i++) { if (di_edid_display_descriptor_get_tag(desc[i]) == DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME) { encode_ascii_string(m.fp, di_edid_display_descriptor_get_string(desc[i])); return memory_stream_close(&m); } } evp = di_edid_get_vendor_product(info->edid); fprintf(m.fp, "0x%04" PRIX16, evp->product); return memory_stream_close(&m); } char * di_info_get_serial(const struct di_info *info) { const struct di_edid_display_descriptor *const *desc; const struct di_edid_vendor_product *evp; struct memory_stream m; size_t i; if (!info->edid) return NULL; if (!memory_stream_open(&m)) return NULL; desc = di_edid_get_display_descriptors(info->edid); for (i = 0; desc[i]; i++) { if (di_edid_display_descriptor_get_tag(desc[i]) == DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL) { encode_ascii_string(m.fp, di_edid_display_descriptor_get_string(desc[i])); return memory_stream_close(&m); } } evp = di_edid_get_vendor_product(info->edid); if (evp->serial != 0) { fprintf(m.fp, "0x%08" PRIX32, evp->serial); return memory_stream_close(&m); } free(memory_stream_close(&m)); return NULL; } dxvk-0~git20230309.275e645/libdisplay-info.map000066400000000000000000000000371440230200600204070ustar00rootroot00000000000000{ global: di_*; local: *; }; dxvk-0~git20230309.275e645/log.c000066400000000000000000000005641440230200600155550ustar00rootroot00000000000000#include "log.h" void _di_logger_va_add_failure(struct di_logger *logger, const char fmt[], va_list args) { if (!logger->initialized) { if (ftell(logger->f) > 0) { fprintf(logger->f, "\n"); } fprintf(logger->f, "%s:\n", logger->section); logger->initialized = true; } fprintf(logger->f, " "); vfprintf(logger->f, fmt, args); fprintf(logger->f, "\n"); } dxvk-0~git20230309.275e645/memory-stream.c000066400000000000000000000026531440230200600175760ustar00rootroot00000000000000#include #include "memory-stream.h" #ifndef _WIN32 bool memory_stream_open(struct memory_stream *m) { *m = (struct memory_stream){ 0 }; m->fp = open_memstream(&m->str, &m->str_len); return m->fp != NULL; } char * memory_stream_close(struct memory_stream *m) { char *str; int ret; ret = fclose(m->fp); str = m->str; *m = (struct memory_stream){ 0 }; if (ret != 0) { free(str); str = NULL; } return str; } #else #include bool memory_stream_open(struct memory_stream *m) { char path[MAX_PATH]; DWORD dwResult; *m = (struct memory_stream){ 0 }; dwResult = GetTempPath(MAX_PATH, path); if ((dwResult > 0) && (dwResult < MAX_PATH)) { char *temp = m->temp; UINT uResult = GetTempFileName(path, "MEMSTREAM", 0, temp); if (uResult != 0) { FILE *f = fopen(temp, "w+b"); if (f != NULL) { m->fp = f; return true; } } } return false; } char * memory_stream_close(struct memory_stream *m) { size_t size; char* str; if (m->fp == NULL) { *m = (struct memory_stream){ 0 }; return NULL; } _fseeki64(m->fp, 0ll, SEEK_END); size = (size_t)_ftelli64(m->fp); _fseeki64(m->fp, 0ll, SEEK_SET); str = malloc(size + 1); if (str == NULL) { fclose(m->fp); remove(m->temp); *m = (struct memory_stream){ 0 }; return NULL; } fread(str, 1, size, m->fp); str[size] = '\0'; fclose(m->fp); remove(m->temp); *m = (struct memory_stream){ 0 }; return str; } #endif dxvk-0~git20230309.275e645/meson.build000066400000000000000000000034521440230200600167710ustar00rootroot00000000000000project( 'libdisplay-info', 'c', version: '0.0.0', license: 'MIT', meson_version: '>= 0.55.0', default_options: [ 'c_std=c11', 'warning_level=3', ], ) pnp_ids = files('pnp.ids') gen_search_table = find_program('tool/gen-search-table.py') pnp_id_table = custom_target( 'pnp-id-table.c', command: [ gen_search_table, pnp_ids, '@OUTPUT@', 'pnp_id_table' ], output: 'pnp-id-table.c', ) cc = meson.get_compiler('c') math = cc.find_library('m', required: false) if cc.get_id() != 'msvc' add_project_arguments(['-D_POSIX_C_SOURCE=200809L'], language: 'c') add_project_arguments(['-Dstatic_array=static'], language: 'c') else add_project_arguments(['-Dstatic_array='], language: 'c') add_project_arguments(['-Dssize_t=intptr_t'], language: 'c') endif add_project_arguments(cc.get_supported_arguments([ '-Wundef', '-Wmissing-prototypes', '-Walloca', '-Wdeclaration-after-statement', '-Wconversion', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Werror=implicit', ]), language: 'c') symbols_file = 'libdisplay-info.map' symbols_flag = '-Wl,--version-script,@0@'.format(meson.current_source_dir() / symbols_file) di_lib = static_library( 'display-info', [ 'cta.c', 'displayid.c', 'dmt-table.c', 'edid.c', 'gtf.c', 'info.c', 'log.c', 'memory-stream.c', pnp_id_table, ], include_directories: include_directories('include'), dependencies: [math], link_args: symbols_flag, link_depends: symbols_file, install: false, ) di_dep = declare_dependency( link_with: di_lib, include_directories: include_directories('include'), ) #di_edid_decode = executable( # 'di-edid-decode', # [ # 'di-edid-decode/cta.c', # 'di-edid-decode/displayid.c', # 'di-edid-decode/edid.c', # 'di-edid-decode/main.c', # ], # dependencies: [di_dep, math], # install: true, #) # #subdir('test') dxvk-0~git20230309.275e645/pnp.ids000066400000000000000000001715761440230200600161420ustar00rootroot00000000000000AAA Avolites Ltd AAE Anatek Electronics Inc. AAM Aava Mobile Oy AAN AAEON Technology Inc. AAT Ann Arbor Technologies ABA ABBAHOME INC. ABC AboCom System Inc. ABD Allen Bradley Company ABE Alcatel Bell ABO D-Link Systems Inc ABS Abaco Systems, Inc. ABT Anchor Bay Technologies, Inc. ABV Advanced Research Technology ACA Ariel Corporation ACB Aculab Ltd ACC Accton Technology Corporation ACD AWETA BV ACE Actek Engineering Pty Ltd ACG A&R Cambridge Ltd. ACH Archtek Telecom Corporation ACI Ancor Communications Inc ACK Acksys ACL Apricot Computers ACM Acroloop Motion Control Systems Inc ACO Allion Computer Inc. ACP Aspen Tech Inc ACR Acer Technologies ACS Altos Computer Systems ACT Applied Creative Technology ACU Acculogic ACV ActivCard S.A ADA Addi-Data GmbH ADB Aldebbaron ADC Acnhor Datacomm ADD Advanced Peripheral Devices Inc ADE Arithmos, Inc. ADH Aerodata Holdings Ltd ADI ADI Systems Inc ADK Adtek System Science Company Ltd ADL ASTRA Security Products Ltd ADM Ad Lib MultiMedia Inc ADN Analog & Digital Devices Tel. Inc ADP Adaptec Inc ADR Nasa Ames Research Center ADS Analog Devices Inc ADT Adtek ADV Advanced Micro Devices Inc ADX Adax Inc ADZ ADDER TECHNOLOGY LTD AEC Antex Electronics Corporation AED Advanced Electronic Designs, Inc. AEI Actiontec Electric Inc AEJ Alpha Electronics Company AEM ASEM S.p.A. AEN Avencall AEP Aetas Peripheral International AET Aethra Telecomunicazioni S.r.l. AFA Alfa Inc AGC Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd. AGI Artish Graphics Inc AGL Argolis AGM Advan Int'l Corporation AGO AlgolTek, Inc. AGT Agilent Technologies AHC Advantech Co., Ltd. AHQ Astro HQ LLC AHS Beijing AnHeng SecoTech Information Technology Co., Ltd. AIC Arnos Insturments & Computer Systems AIE Altmann Industrieelektronik AII Amptron International Inc. AIK Dongguan Alllike Electronics Co., Ltd. AIL Altos India Ltd AIM AIMS Lab Inc AIR Advanced Integ. Research Inc AIS Alien Internet Services AIW Aiwa Company Ltd AIX ALTINEX, INC. AJA AJA Video Systems, Inc. AKB Akebia Ltd AKE AKAMI Electric Co.,Ltd AKI AKIA Corporation AKL AMiT Ltd AKM Asahi Kasei Microsystems Company Ltd AKP Atom Komplex Prylad AKR Anker Innovations Limited AKY Askey Computer Corporation ALA Alacron Inc ALC Altec Corporation ALD In4S Inc ALE Alenco BV ALG Realtek Semiconductor Corp. ALH AL Systems ALI Acer Labs ALJ Altec Lansing ALK Acrolink Inc ALL Alliance Semiconductor Corporation ALM Acutec Ltd. ALN Alana Technologies ALO Algolith Inc. ALP ALPS ALPINE CO., LTD. ALR Advanced Logic ALS Avance Logic Inc ALT Altra ALV AlphaView LCD ALX ALEXON Co.,Ltd. AMA Asia Microelectronic Development Inc AMB Ambient Technologies, Inc. AMC Attachmate Corporation AMD Amdek Corporation AMI American Megatrends Inc AML Anderson Multimedia Communications (HK) Limited AMN Amimon LTD. AMO Amino Technologies PLC and Amino Communications Limited AMP AMP Inc AMR AmTRAN Technology Co., Ltd. AMS ARMSTEL, Inc. AMT AMT International Industry AMX AMX LLC ANA Anakron ANC Ancot AND Adtran Inc ANI Anigma Inc ANK Anko Electronic Company Ltd ANL Analogix Semiconductor, Inc ANO Anorad Corporation ANP Andrew Network Production ANR ANR Ltd ANS Ansel Communication Company ANT Ace CAD Enterprise Company Ltd ANV Beijing ANTVR Technology Co., Ltd. ANW Analog Way SAS ANX Acer Netxus Inc AOA AOpen Inc. AOE Advanced Optics Electronics, Inc. AOL America OnLine AOT Alcatel APC American Power Conversion APD AppliAdata APE ALPS ALPINE CO., LTD. APG Horner Electric Inc API A Plus Info Corporation APL Aplicom Oy APM Applied Memory Tech APN Appian Tech Inc APP Apple Computer Inc APR Aprilia s.p.a. APS Autologic Inc APT Audio Processing Technology Ltd APV A+V Link APX AP Designs Ltd ARC Alta Research Corporation ARD AREC Inc. ARE ICET S.p.A. ARG Argus Electronics Co., LTD ARI Argosy Research Inc ARK Ark Logic Inc ARL Arlotto Comnet Inc ARM Arima ARO Poso International B.V. ARR ARRIS Group, Inc. ARS Arescom Inc ART Corion Industrial Corporation ASC Ascom Strategic Technology Unit ASD USC Information Sciences Institute ASE AseV Display Labs ASH Ashton Bentley Concepts ASI Ahead Systems ASK Ask A/S ASL AccuScene Corporation Ltd ASM ASEM S.p.A. ASN Asante Tech Inc ASP ASP Microelectronics Ltd AST AST Research Inc ASU Asuscom Network Inc ASX AudioScience ASY Rockwell Collins / Airshow Systems ATA Allied Telesyn International (Asia) Pte Ltd ATC Ably-Tech Corporation ATD Alpha Telecom Inc ATE Innovate Ltd ATH Athena Informatica S.R.L. ATI Allied Telesis KK ATJ ArchiTek Corporation ATK Allied Telesyn Int'l ATL Arcus Technology Ltd ATM ATM Ltd ATN Athena Smartcard Solutions Ltd. ATO ASTRO DESIGN, INC. ATP Alpha-Top Corporation ATT AT&T ATV Office Depot, Inc. ATX Athenix Corporation AUD AudioControl AUG August Home, Inc. AUI ALPS ALPINE CO., LTD. AUO AU Optronics AUR Aureal Semiconductor AUS ASUSTek COMPUTER INC AUT Autotime Corporation AUV Auvidea GmbH AVA Avaya Communication AVC Auravision Corporation AVD Avid Electronics Corporation AVE Add Value Enterpises (Asia) Pte Ltd AVG Avegant Corporation AVI Nippon Avionics Co.,Ltd AVJ Atelier Vision Corporation AVL Avalue Technology Inc. AVM AVM GmbH AVN Advance Computer Corporation AVO Avocent Corporation AVR AVer Information Inc. AVS Avatron Software Inc. AVT Avtek (Electronics) Pty Ltd AVV SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.) AVX A/Vaux Electronics AWC Access Works Comm Inc AWL Aironet Wireless Communications, Inc AWS Wave Systems AXB Adrienne Electronics Corporation AXC AXIOMTEK CO., LTD. AXE Axell Corporation AXI American Magnetics AXL Axel AXO Axonic Labs LLC AXP American Express AXT Axtend Technologies Inc AXX Axxon Computer Corporation AXY AXYZ Automation Services, Inc AYD Aydin Displays AYR Airlib, Inc AZH Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group) AZM AZ Middelheim - Radiotherapy AZT Aztech Systems Ltd BAC Biometric Access Corporation BAN Banyan BBB an-najah university BBH B&Bh BBL Brain Boxes Limited BBV BlueBox Video Limited BBX Black Box Corporation BCC Beaver Computer Corporaton BCD Barco GmbH BCI Broadata Communications Inc. BCK Beck GmbH & Co. Elektronik Bauelemente KG BCM Broadcom BCQ Deutsche Telekom Berkom GmbH BCS Booria CAD/CAM systems BDO Brahler ICS BDR Blonder Tongue Labs, Inc. BDS Barco Display Systems BEC Beckhoff Automation BEI Beckworth Enterprises Inc BEK Beko Elektronik A.S. BEL Beltronic Industrieelektronik GmbH BEO Baug & Olufsen BFE B.F. Engineering Corporation BGB Barco Graphics N.V BGT Budzetron Inc BHZ BitHeadz, Inc. BIA Biamp Systems Corporation BIC Big Island Communications BIG Bigscreen, Inc. BII Boeckeler Instruments Inc BIL Billion Electric Company Ltd BIO BioLink Technologies International, Inc. BIT Bit 3 Computer BLD BILD INNOVATIVE TECHNOLOGY LLC BLI Busicom BLN BioLink Technologies BLP Bloomberg L.P. BMD Blackmagic Design BMI Benson Medical Instruments Company BML BIOMED Lab BMS BIOMEDISYS BNE Bull AB BNK Banksia Tech Pty Ltd BNO Bang & Olufsen BNS Boulder Nonlinear Systems BOB Rainy Orchard BOE BOE BOI NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD BOS BOS BPD Micro Solutions, Inc. BPS Barco, N.V. BPU Best Power BRA Braemac Pty Ltd BRC BARC BRG Bridge Information Co., Ltd BRI Boca Research Inc BRM Braemar Inc BRO BROTHER INDUSTRIES,LTD. BSE Bose Corporation BSG Robert Bosch GmbH BSL Biomedical Systems Laboratory BSN BRIGHTSIGN, LLC BST BodySound Technologies, Inc. BTC Bit 3 Computer BTE Brilliant Technology BTF Bitfield Oy BTI BusTech Inc BTO BioTao Ltd BUF Yasuhiko Shirai Melco Inc BUG B.U.G., Inc. BUJ ATI Tech Inc BUL Bull BUR B&R Industrial Automation GmbH BUS BusTek BUT 21ST CENTURY ENTERTAINMENT BWK Bitworks Inc. BXE Buxco Electronics BYD byd:sign corporation CAA Castles Automation Co., Ltd CAC CA & F Elettronica CAG CalComp CAI Canon Inc. CAL Acon CAM Cambridge Audio CAN Canopus Company Ltd CAR Cardinal Company Ltd CAS CASIO COMPUTER CO.,LTD CAT Consultancy in Advanced Technology CAV Cavium Networks, Inc CBI ComputerBoards Inc CBR Cebra Tech A/S CBT Cabletime Ltd CBX Cybex Computer Products Corporation CCC C-Cube Microsystems CCI Cache CCJ CONTEC CO.,LTD. CCL CCL/ITRI CCP Capetronic USA Inc CDC Core Dynamics Corporation CDD Convergent Data Devices CDE Colin.de CDG Christie Digital Systems Inc CDI Concept Development Inc CDK Cray Communications CDN Codenoll Technical Corporation CDP CalComp CDS Computer Diagnostic Systems CDT IBM Corporation CDV Convergent Design Inc. CEA Consumer Electronics Association CEC Chicony Electronics Company Ltd CED Cambridge Electronic Design Ltd CEF Cefar Digital Vision CEI Crestron Electronics, Inc. CEM MEC Electronics GmbH CEN Centurion Technologies P/L CEP C-DAC CER Ceronix CET TEC CORPORATION CFG Atlantis CFR Meta View, Inc. CGA Chunghwa Picture Tubes, LTD CGS Chyron Corp CGT congatec AG CHA Chase Research PLC CHD ChangHong Electric Co.,Ltd CHE Acer Inc CHG Sichuan Changhong Electric CO, LTD. CHI Chrontel Inc CHL Chloride-R&D CHM CHIC TECHNOLOGY CORP. CHO Sichuang Changhong Corporation CHP CH Products CHR christmann informationstechnik + medien GmbH & Co. KG CHS Agentur Chairos CHT Chunghwa Picture Tubes,LTD. CHY Cherry GmbH CIC Comm. Intelligence Corporation CIE Convergent Engineering, Inc. CII Cromack Industries Inc CIL Citicom Infotech Private Limited CIN Citron GmbH CIP Ciprico Inc CIR Cirrus Logic Inc CIS Cisco Systems Inc CIT Citifax Limited CKC The Concept Keyboard Company Ltd CKJ Carina System Co., Ltd. CLA Clarion Company Ltd CLD COMMAT L.t.d. CLE Classe Audio CLG CoreLogic CLI Cirrus Logic Inc CLM CrystaLake Multimedia CLO Clone Computers CLR Clover Electronics CLT automated computer control systems CLV Clevo Company CLX CardLogix CMC CMC Ltd CMD Colorado MicroDisplay, Inc. CMG Chenming Mold Ind. Corp. CMI C-Media Electronics CMK Comark LLC CMM Comtime GmbH CMN Chimei Innolux Corporation CMO Chi Mei Optoelectronics corp. CMR Cambridge Research Systems Ltd CMS CompuMaster Srl CMX Comex Electronics AB CNB American Power Conversion CNC Alvedon Computers Ltd CND Micro-Star Int'l Co., Ltd. CNE Cine-tal CNI Connect Int'l A/S CNN Canon Inc CNT COINT Multimedia Systems COB COBY Electronics Co., Ltd COD CODAN Pty. Ltd. COI Codec Inc. COL Rockwell Collins, Inc. COM Comtrol Corporation CON Contec Company Ltd COO coolux GmbH COR Corollary Inc COS CoStar Corporation COT Core Technology Inc COW Polycow Productions COX Comrex CPC Ciprico Inc CPD CompuAdd CPI Computer Peripherals Inc CPL Compal Electronics Inc CPM Capella Microsystems Inc. CPP Compound Photonics CPQ Compaq Computer Company CPT cPATH CPX Powermatic Data Systems CRA CRALTECH ELECTRONICA, S.L. CRC CONRAC GmbH CRD Cardinal Technical Inc CRE Creative Labs Inc CRH Contemporary Research Corp. CRI Crio Inc. CRL Creative Logic CRM CORSAIR MEMORY Inc. CRN Cornerstone Imaging CRO Extraordinary Technologies PTY Limited CRQ Cirque Corporation CRS Crescendo Communication Inc CRV Cerevo Inc. CRW Cammegh Limited CRX Cyrix Corporation CSB Transtex SA CSC Crystal Semiconductor CSD Cresta Systems Inc CSE Concept Solutions & Engineering CSI Cabletron System Inc CSL Cloudium Systems Ltd. CSM Cosmic Engineering Inc. CSO California Institute of Technology CSS CSS Laboratories CST CSTI Inc CTA CoSystems Inc CTC CTC Communication Development Company Ltd CTE Chunghwa Telecom Co., Ltd. CTL Creative Technology Ltd CTM Computerm Corporation CTN Computone Products CTP Computer Technology Corporation CTR Control4 Corporation CTS Comtec Systems Co., Ltd. CTX Creatix Polymedia GmbH CUB Cubix Corporation CUK Calibre UK Ltd CVA Covia Inc. CVI Colorado Video, Inc. CVP Chromatec Video Products Ltd CVS Clarity Visual Systems CWC Curtiss-Wright Controls, Inc. CWR Connectware Inc CXT Conexant Systems CYB CyberVision CYC Cylink Corporation CYD Cyclades Corporation CYL Cyberlabs CYP CYPRESS SEMICONDUCTOR CORPORATION CYT Cytechinfo Inc CYV Cyviz AS CYW Cyberware CYX Cyrix Corporation CZC Shenzhen ChuangZhiCheng Technology Co., Ltd. CZE Carl Zeiss AG DAC Digital Acoustics Corporation DAE Digatron Industrie Elektronik GmbH DAI DAIS SET Ltd. DAK Daktronics DAL Digital Audio Labs Inc DAN Danelec Marine A/S DAS DAVIS AS DAT Datel Inc DAU Daou Tech Inc DAV Davicom Semiconductor Inc DAW DA2 Technologies Inc DAX Data Apex Ltd DBD Diebold Inc. DBI DigiBoard Inc DBK Databook Inc DBL Doble Engineering Company DBN DB Networks Inc DCA Digital Communications Association DCC Dale Computer Corporation DCD Datacast LLC DCE dSPACE GmbH DCI Concepts Inc DCL Dynamic Controls Ltd DCM DCM Data Products DCO Dialogue Technology Corporation DCR Decros Ltd DCS Diamond Computer Systems Inc DCT Dancall Telecom A/S DCV Datatronics Technology Inc DDA DA2 Technologies Corporation DDD Danka Data Devices DDE Datasat Digital Entertainment DDI Data Display AG DDS Barco, N.V. DDT Datadesk Technologies Inc DDV Delta Information Systems, Inc DEC Digital Equipment Corporation DEI Deico Electronics DEL Dell Inc. DEN Densitron Computers Ltd DEX idex displays DFI DFI DFK SharkTec A/S DFT DEI Holdings dba Definitive Technology DGA Digiital Arts Inc DGC Data General Corporation DGI DIGI International DGK DugoTech Co., LTD DGP Digicorp European sales S.A. DGS Diagsoft Inc DGT Dearborn Group Technology DHD Dension Audio Systems DHP DH Print DHQ Quadram DHT Projectavision Inc DIA Diadem DIG Digicom S.p.A. DII Dataq Instruments Inc DIM dPict Imaging, Inc. DIN Daintelecom Co., Ltd DIS Diseda S.A. DIT Dragon Information Technology DJE Capstone Visual Product Development DJP Maygay Machines, Ltd DKY Datakey Inc DLB Dolby Laboratories Inc. DLC Diamond Lane Comm. Corporation DLG Digital-Logic GmbH DLK D-Link Systems Inc DLL Dell Inc DLM DLOGIC Ltd. DLO Shenzhen Dlodlo Technologies Co., Ltd. DLT Digitelec Informatique Park Cadera DMB Digicom Systems Inc DMC Dune Microsystems Corporation DMG Monoprice.Inc DMM Dimond Multimedia Systems Inc DMN Dimension Engineering LLC DMO Data Modul AG DMP D&M Holdings Inc, Professional Business Company DMS DOME imaging systems DMT Distributed Management Task Force, Inc. (DMTF) DMV NDS Ltd DNA DNA Enterprises, Inc. DNG Apache Micro Peripherals Inc DNI Deterministic Networks Inc. DNT Dr. Neuhous Telekommunikation GmbH DNV DiCon DOL Dolman Technologies Group Inc DOM Dome Imaging Systems DON DENON, Ltd. DOT Dotronic Mikroelektronik GmbH DPA DigiTalk Pro AV DPC Delta Electronics Inc DPH Delphi Automotive LLP DPI DocuPoint DPL Digital Projection Limited DPM ADPM Synthesis sas DPN Shanghai Lexiang Technology Limited DPS Digital Processing Systems DPT DPT DPX DpiX, Inc. DQB Datacube Inc DRB Dr. Bott KG DRC Data Ray Corp. DRD DIGITAL REFLECTION INC. DRI Data Race Inc DRS DRS Defense Solutions, LLC DSA Display Solution AG DSD DS Multimedia Pte Ltd DSG Disguise Technologies DSI Digitan Systems Inc DSJ VR Technology Holdings Limited DSM DSM Digital Services GmbH DSP Domain Technology Inc DTA DELTATEC DTC DTC Tech Corporation DTE Dimension Technologies, Inc. DTI Diversified Technology, Inc. DTK Dynax Electronics (HK) Ltd DTL e-Net Inc DTN Datang Telephone Co DTO Deutsche Thomson OHG DTT Design & Test Technology, Inc. DTX Data Translation DUA Dosch & Amand GmbH & Company KG DUN NCR Corporation DVD Dictaphone Corporation DVL Devolo AG DVS Digital Video System DVT Data Video DWE Daewoo Electronics Company Ltd DXC Digipronix Control Systems DXD DECIMATOR DESIGN PTY LTD DXL Dextera Labs Inc DXP Data Expert Corporation DXS Signet DYC Dycam Inc DYM Dymo-CoStar Corporation DYN Askey Computer Corporation DYX Dynax Electronics (HK) Ltd EAG ELTEC Elektronik AG EAS Evans and Sutherland Computer EBH Data Price Informatica EBS EBS Euchner Büro- und Schulsysteme GmbH EBT HUALONG TECHNOLOGY CO., LTD ECA Electro Cam Corp. ECC ESSential Comm. Corporation ECH EchoStar Corporation ECI Enciris Technologies ECK Eugene Chukhlomin Sole Proprietorship, d.b.a. ECL Excel Company Ltd ECM E-Cmos Tech Corporation ECO Echo Speech Corporation ECP Elecom Company Ltd ECS Elitegroup Computer Systems Company Ltd ECT Enciris Technologies EDC e.Digital Corporation EDG Electronic-Design GmbH EDI Edimax Tech. Company Ltd EDM EDMI EDT Emerging Display Technologies Corp EEE ET&T Technology Company Ltd EEH EEH Datalink GmbH EEP E.E.P.D. GmbH EES EE Solutions, Inc. EGA Elgato Systems LLC EGD EIZO GmbH Display Technologies EGL Eagle Technology EGN Egenera, Inc. EGO Ergo Electronics EHJ Epson Research EHN Enhansoft EIC Eicon Technology Corporation EIN Elegant Invention EKA MagTek Inc. EKC Eastman Kodak Company EKS EKSEN YAZILIM ELA ELAD srl ELC Electro Scientific Ind ELD Express Luck, Inc. ELE Elecom Company Ltd ELG Elmeg GmbH Kommunikationstechnik ELI Edsun Laboratories ELL Electrosonic Ltd ELM Elmic Systems Inc ELO Elo TouchSystems Inc ELS ELSA GmbH ELT Element Labs, Inc. ELU Express Industrial, Ltd. ELX Elonex PLC EMB Embedded computing inc ltd EMC eMicro Corporation EMD Embrionix Design Inc. EME EMiNE TECHNOLOGY COMPANY, LTD. EMG EMG Consultants Inc EMI Ex Machina Inc EMK Emcore Corporation EMO ELMO COMPANY, LIMITED EMR ICC Intelligent Platforms GmbH EMU Emulex Corporation ENC Eizo Nanao Corporation END ENIDAN Technologies Ltd ENE ENE Technology Inc. ENI Efficient Networks ENS Ensoniq Corporation ENT Enterprise Comm. & Computing Inc EON Eon Instrumentation, Inc. EPC Empac EPH Epiphan Systems Inc. EPI Envision Peripherals, Inc EPN EPiCON Inc. EPS KEPS EQP Equipe Electronics Ltd. EQX Equinox Systems Inc ERG Ergo System ERI Ericsson Mobile Communications AB ERN Ericsson, Inc. ERP Euraplan GmbH ERS Eizo Rugged Solutions ERT Escort Insturments Corporation ESA Elbit Systems of America ESB ScioTeq ESC Eden Sistemas de Computacao S/A ESD Ensemble Designs, Inc ESG ELCON Systemtechnik GmbH ESI Extended Systems, Inc. ESK ES&S ESL Esterline Technologies ESN eSATURNUS ESS ESS Technology Inc EST Embedded Solution Technology ESY E-Systems Inc ETC Everton Technology Company Ltd ETD ELAN MICROELECTRONICS CORPORATION ETG Eizo Technologies GmbH ETH Etherboot Project ETI Eclipse Tech Inc ETK eTEK Labs Inc. ETL Evertz Microsystems Ltd. ETS Electronic Trade Solutions Ltd ETT E-Tech Inc EUT Ericsson Mobile Networks B.V. EVE Advanced Micro Peripherals Ltd EVI eviateg GmbH EVP EverPro Technologies Company Limited EVX Everex EXA Exabyte EXC Excession Audio EXI Exide Electronics EXN RGB Systems, Inc. dba Extron Electronics EXP Data Export Corporation EXR Explorer Inc. EXT Exatech Computadores & Servicos Ltda EXX Exxact GmbH EXY Exterity Ltd EYE eyevis GmbH EYF eyefactive Gmbh EZE EzE Technologies EZP Storm Technology FAN Fantalooks Co., Ltd. FAR Farallon Computing FBI Interface Corporation FCB Furukawa Electric Company Ltd FCG First International Computer Ltd FCS Focus Enhancements, Inc. FDC Future Domain FDD Forth Dimension Displays Ltd FDI Future Designs, Inc. FDT Fujitsu Display Technologies Corp. FDX Findex, Inc. FEC FURUNO ELECTRIC CO., LTD. FEL Fellowes & Questec FEN Fen Systems Ltd. FER Ferranti Int'L FFC FUJIFILM Corporation FFI Fairfield Industries FGD Lisa Draexlmaier GmbH FGL Fujitsu General Limited. FHL FHLP FIC Formosa Industrial Computing Inc FIL Forefront Int'l Ltd FIN Finecom Co., Ltd. FIR Chaplet Systems Inc FIS FLY-IT Simulators FIT Feature Integration Technology Inc. FJC Fujitsu Takamisawa Component Limited FJS Fujitsu Spain FJT F.J. Tieman BV FLE ADTI Media, Inc FLI Faroudja Laboratories FLY Butterfly Communications FMA Fast Multimedia AG FMC Ford Microelectronics Inc FMI Fellowes, Inc. FML Fujitsu Microelect Ltd FMZ Formoza-Altair FNC Fanuc LTD FNI Funai Electric Co., Ltd. FOA FOR-A Company Limited FOK Fokus Technologies GmbH FOS Foss Tecator FOV FOVE INC FOX HON HAI PRECISION IND.CO.,LTD. FPC Fingerprint Cards AB FPE Fujitsu Peripherals Ltd FPS Deltec Corporation FPX Cirel Systemes FRC Force Computers FRD Freedom Scientific BLV FRE Forvus Research Inc FRI Fibernet Research Inc FRO FARO Technologies FRS South Mountain Technologies, LTD FSC Future Systems Consulting KK FSI Fore Systems Inc FST Modesto PC Inc FTC Futuretouch Corporation FTE Frontline Test Equipment Inc. FTG FTG Data Systems FTI FastPoint Technologies, Inc. FTL FUJITSU TEN LIMITED FTN Fountain Technologies Inc FTR Mediasonic FTS FocalTech Systems Co., Ltd. FTW MindTribe Product Engineering, Inc. FUJ Fujitsu Ltd FUL Fun Technology Innovation INC. FUN sisel muhendislik FUS Fujitsu Siemens Computers GmbH FVC First Virtual Corporation FVX C-C-C Group Plc FWA Attero Tech, LLC FWR Flat Connections Inc FXX Fuji Xerox FZC Founder Group Shenzhen Co. FZI FZI Forschungszentrum Informatik GAC GreenArrays, Inc. GAG Gage Applied Sciences Inc GAL Galil Motion Control GAU Gaudi Co., Ltd. GBT GIGA-BYTE TECHNOLOGY CO., LTD. GCC GCC Technologies Inc GCI Gateway Comm. Inc GCS Grey Cell Systems Ltd GDC General Datacom GDI G. Diehl ISDN GmbH GDS GDS GDT Vortex Computersysteme GmbH GEC Gechic Corporation GED General Dynamics C4 Systems GEF GE Fanuc Embedded Systems GEH Abaco Systems, Inc. GEM Gem Plus GEN Genesys ATE Inc GEO GEO Sense GER GERMANEERS GmbH GES GES Singapore Pte Ltd GET Getac Technology Corporation GFM GFMesstechnik GmbH GFN Gefen Inc. GGL Google Inc. GGT G2TOUCH KOREA GIC General Inst. Corporation GIM Guillemont International GIP GI Provision Ltd GIS AT&T Global Info Solutions GJN Grand Junction Networks GLD Goldmund - Digital Audio SA GLE AD electronics GLM Genesys Logic GLS Gadget Labs LLC GMK GMK Electronic Design GmbH GML General Information Systems GMM GMM Research Inc GMN GEMINI 2000 Ltd GMX GMX Inc GND Gennum Corporation GNN GN Nettest Inc GNZ Gunze Ltd GOE GOEPEL electronic GmbH GPR GoPro, Inc. GRA Graphica Computer GRE GOLD RAIN ENTERPRISES CORP. GRH Granch Ltd GRM Garmin International GRV Advanced Gravis GRY Robert Gray Company GSB NIPPONDENCHI CO,.LTD GSC General Standards Corporation GSM LG Electronics GSN Grandstream Networks, Inc. GST Graphic SystemTechnology GSY Grossenbacher Systeme AG GTC Graphtec Corporation GTI Goldtouch GTK G-Tech Corporation GTM Garnet System Company Ltd GTS Geotest Marvin Test Systems Inc GTT General Touch Technology Co., Ltd. GUD Guntermann & Drunck GmbH GUP GoUp Co.,Ltd GUZ Guzik Technical Enterprises GVC GVC Corporation GVL Global Village Communication GVS G.VISION GWI GW Instruments GWK Gateworks Corporation GWY Gateway 2000 GXL Galaxy Microsystems Ltd. GZE GUNZE Limited HAE Haider electronics HAI Haivision Systems Inc. HAL Halberthal HAN Hanchang System Corporation HAR Harris Corporation HAY Hayes Microcomputer Products Inc HCA DAT HCE Hitachi Consumer Electronics Co., Ltd HCL HCL America Inc HCM HCL Peripherals HCP Hitachi Computer Products Inc HCW Hauppauge Computer Works Inc HDC HardCom Elektronik & Datateknik HDI HD-INFO d.o.o. HDV Holografika kft. HEC Hisense Electric Co., Ltd. HEL Hitachi Micro Systems Europe Ltd HER Ascom Business Systems HET HETEC Datensysteme GmbH HHC HIRAKAWA HEWTECH CORP. HHI Fraunhofer Heinrich-Hertz-Institute HHT Hitevision Group HIB Hibino Corporation HIC Hitachi Information Technology Co., Ltd. HII Harman International Industries, Inc HIK Hikom Co., Ltd. HIL Hilevel Technology HIQ Kaohsiung Opto Electronics Americas, Inc. HIS Hope Industrial Systems, Inc. HIT Hitachi America Ltd HJI Harris & Jeffries Inc HKA HONKO MFG. CO., LTD. HKC HKC OVERSEAS LIMITED HKG Josef Heim KG HLG China Hualu Group Co., Ltd. HMC Hualon Microelectric Corporation HMK hmk Daten-System-Technik BmbH HMX HUMAX Co., Ltd. HNS Hughes Network Systems HOB HOB Electronic GmbH HOE Hosiden Corporation HOL Holoeye Photonics AG HON Sonitronix HPA Zytor Communications HPC Hewlett-Packard Co. HPD Hewlett Packard HPE Hewlett Packard Enterprise HPI Headplay, Inc. HPK HAMAMATSU PHOTONICS K.K. HPN HP Inc. HPQ Hewlett-Packard Co. HPR H.P.R. Electronics GmbH HRC Hercules HRE Qingdao Haier Electronics Co., Ltd. HRI Hall Research HRL Herolab GmbH HRS Harris Semiconductor HRT HERCULES HSC Hagiwara Sys-Com Company Ltd HSD HannStar Display Corp HSM AT&T Microelectronics HSN Hansung Co., Ltd HSP HannStar Display Corp HST Horsent Technology Co., Ltd. HTC Hitachi Ltd HTI Hampshire Company, Inc. HTK Holtek Microelectronics Inc HTL HTBLuVA Mödling HTR Shenzhen ZhuoYi HengTong Computer Technology Limited HTX Hitex Systementwicklung GmbH HUB GAI-Tronics, A Hubbell Company HUK Hoffmann + Krippner GmbH HUM IMP Electronics Ltd. HVR HTC Corportation HWA Harris Canada Inc HWC DBA Hans Wedemeyer HWD Highwater Designs Ltd HWP Hewlett Packard HWV Huawei Technologies Co., Inc. HXM Hexium Ltd. HYC Hypercope Gmbh Aachen HYD Hydis Technologies.Co.,LTD HYL Shanghai Chai Ming Huang Info&Tech Co, Ltd HYO HYC CO., LTD. HYP Hyphen Ltd HYR Hypertec Pty Ltd HYT Heng Yu Technology (HK) Limited HYV Hynix Semiconductor IAD IAdea Corporation IAF Institut f r angewandte Funksystemtechnik GmbH IAI Integration Associates, Inc. IAT IAT Germany GmbH IBC Integrated Business Systems IBI INBINE.CO.LTD IBM IBM Brasil IBP IBP Instruments GmbH IBR IBR GmbH ICA ICA Inc ICC BICC Data Networks Ltd ICD ICD Inc ICE IC Ensemble ICI Infotek Communication Inc ICM Intracom SA ICN Sanyo Icon ICO Intel Corp ICP ICP Electronics, Inc./iEi Technology Corp. ICR Icron ICS Integrated Circuit Systems ICV Inside Contactless ICX ICCC A/S IDC International Datacasting Corporation IDE IDE Associates IDK IDK Corporation IDN Idneo Technologies IDO IDEO Product Development IDP Integrated Device Technology, Inc. IDS Interdigital Sistemas de Informacao IDT International Display Technology IDX IDEXX Labs IEC Interlace Engineering Corporation IEE IEE IEI Interlink Electronics IFS In Focus Systems Inc IFT Informtech IFX Infineon Technologies AG IFZ Infinite Z IGC Intergate Pty Ltd IGM IGM Communi IHE InHand Electronics IIC ISIC Innoscan Industrial Computers A/S III Intelligent Instrumentation IIN IINFRA Co., Ltd IIT Informatik Information Technologies IKE Ikegami Tsushinki Co. Ltd. IKS Ikos Systems Inc ILC Image Logic Corporation ILS Innotech Corporation IMA Imagraph IMB ART s.r.l. IMC IMC Networks IMD ImasDe Canarias S.A. IME Imagraph IMF Immersive Audio Technologies France IMG IMAGENICS Co., Ltd. IMI International Microsystems Inc IMM Immersion Corporation IMN Impossible Production IMP Impinj IMT Inmax Technology Corporation IMX arpara Technology Co., Ltd. INA Inventec Corporation INC Home Row Inc IND ILC INE Inventec Electronics (M) Sdn. Bhd. INF Inframetrics Inc ING Integraph Corporation INI Initio Corporation INK Indtek Co., Ltd. INL InnoLux Display Corporation INM InnoMedia Inc INN Innovent Systems, Inc. INO Innolab Pte Ltd INP Interphase Corporation INS Ines GmbH INT Interphase Corporation inu Inovatec S.p.A. INV Inviso, Inc. INX Communications Supply Corporation (A division of WESCO) INZ Best Buy IOA CRE Technology Corporation IOC Guangxi Century Innovation Display Electronics Co., Ltd IOD I-O Data Device Inc IOM Iomega ION Inside Out Networks IOS i-O Display System IOT I/OTech Inc IPC IPC Corporation IPD Industrial Products Design, Inc. IPI Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell) IPM IPM Industria Politecnica Meridionale SpA IPN Performance Technologies IPP IP Power Technologies GmbH IPQ IP3 Technology Ltd. IPR Ithaca Peripherals IPS IPS, Inc. (Intellectual Property Solutions, Inc.) IPT International Power Technologies IPW IPWireless, Inc IQI IneoQuest Technologies, Inc IQT IMAGEQUEST Co., Ltd IRD Irdata ISA Symbol Technologies ISC Id3 Semiconductors ISG Insignia Solutions Inc ISI Interface Solutions ISL Isolation Systems ISM Image Stream Medical ISP IntreSource Systems Pte Ltd ISR INSIS Co., LTD. ISS ISS Inc IST Intersolve Technologies ISY International Integrated Systems,Inc.(IISI) ITA Itausa Export North America ITC Intercom Inc ITD Internet Technology Corporation ITE Integrated Tech Express Inc ITI VanErum Group ITK ITK Telekommunikation AG ITL Inter-Tel ITM ITM inc. ITN The NTI Group ITP IT-PRO Consulting und Systemhaus GmbH ITR Infotronic America, Inc. ITS IDTECH ITT I&T Telecom. ITX integrated Technology Express Inc IUC ICSL IVI Intervoice Inc IVM Iiyama North America IVR Inlife-Handnet Co., Ltd. IVS Intevac Photonics Inc. IWR Icuiti Corporation IWX Intelliworxx, Inc. IXD Intertex Data AB IXN Shenzhen Inet Mobile Internet Technology Co., LTD JAC Astec Inc JAE Japan Aviation Electronics Industry, Limited JAS Janz Automationssysteme AG JAT Jaton Corporation JAZ Carrera Computer Inc JCE Jace Tech Inc JDI Japan Display Inc. JDL Japan Digital Laboratory Co.,Ltd. JEM Japan E.M.Solutions Co., Ltd. JEN N-Vision JET JET POWER TECHNOLOGY CO., LTD. JFX Jones Futurex Inc JGD University College JIC Jaeik Information & Communication Co., Ltd. JKC JVC KENWOOD Corporation JMT Micro Technical Company Ltd JPC JPC Technology Limited JPW Wallis Hamilton Industries JQE CNet Technical Inc JSD JS DigiTech, Inc JSI Jupiter Systems, Inc. JSK SANKEN ELECTRIC CO., LTD JTS JS Motorsports JTY jetway security micro,inc JUK Janich & Klass Computertechnik GmbH JUP Jupiter Systems JVC JVC JWD Video International Inc. JWL Jewell Instruments, LLC JWS JWSpencer & Co. JWY Jetway Information Co., Ltd KAR Karna KBI Kidboard Inc KBL Kobil Systems GmbH KCD Chunichi Denshi Co.,LTD. KCL Keycorp Ltd KDE KDE KDK Kodiak Tech KDM Korea Data Systems Co., Ltd. KDS KDS USA KDT KDDI Technology Corporation KEC Kyushu Electronics Systems Inc KEM Kontron Embedded Modules GmbH KES Kesa Corporation KEU Kontron Europe GmbH KEY Key Tech Inc KFC SCD Tech KFE Komatsu Forest KFX Kofax Image Products KGI Klipsch Group, Inc KGL KEISOKU GIKEN Co.,Ltd. KIO Kionix, Inc. KIS KiSS Technology A/S KLT Colorlight KMC Mitsumi Company Ltd KME KIMIN Electronics Co., Ltd. KML Kensington Microware Ltd KMR Kramer Electronics Ltd. International KNC Konica corporation KNX Nutech Marketing PTL KOB Kobil Systems GmbH KOD Eastman Kodak Company KOE KOLTER ELECTRONIC KOL Kollmorgen Motion Technologies Group KOM Kontron GmbH KOP Kopin Corporation KOU KOUZIRO Co.,Ltd. KOW KOWA Company,LTD. KPC King Phoenix Company KPT TPK Holding Co., Ltd KRL Krell Industries Inc. KRM Kroma Telecom KRY Kroy LLC KSC Kinetic Systems Corporation KSG KUPA China Shenzhen Micro Technology Co., Ltd. Gold Institute KSL Karn Solutions Ltd. KSX King Tester Corporation KTC Kingston Tech Corporation KTD Takahata Electronics Co.,Ltd. KTE K-Tech KTG Kayser-Threde GmbH KTI Konica Technical Inc KTK Key Tronic Corporation KTN Katron Tech Inc KTS Kyokko Communication System Co., Ltd. KUR Kurta Corporation KVA Kvaser AB KVX KeyView KWD Kenwood Corporation KYC Kyocera Corporation KYE KYE Syst Corporation KYK Samsung Electronics America Inc KYN KEYENCE CORPORATION KZI K-Zone International co. Ltd. KZN K-Zone International LAB ACT Labs Ltd LAC LaCie LAF Microline LAG Laguna Systems LAN Sodeman Lancom Inc LAS LASAT Comm. A/S LAV Lava Computer MFG Inc LBO Lubosoft LCC LCI LCD Toshiba Matsushita Display Technology Co., Ltd LCE La Commande Electronique LCI Lite-On Communication Inc LCM Latitude Comm. LCN LEXICON LCP Silent Power Electronics GmbH LCS Longshine Electronics Company LCT Labcal Technologies LDN Laserdyne Technologies LDT LogiDataTech Electronic GmbH LEC Lectron Company Ltd LED Long Engineering Design Inc LEG Legerity, Inc LEN Lenovo Group Limited LEO First International Computer Inc LEX Lexical Ltd LGC Logic Ltd LGD LG Display LGI Logitech Inc LGS LG Semicom Company Ltd LGX Lasergraphics, Inc. LHA Lars Haagh ApS LHC Beihai Century Joint Innovation Technology Co.,Ltd LHE Lung Hwa Electronics Company Ltd LHT Lighthouse Technologies Limited LIN Lenovo Beijing Co. Ltd. LIP Linked IP GmbH LIS Life is Style Inc. LIT Lithics Silicon Technology LJX Datalogic Corporation LKM Likom Technology Sdn. Bhd. LLL L-3 Communications LMG Lucent Technologies LMI Lexmark Int'l Inc LMP Leda Media Products LMT Laser Master LND Land Computer Company Ltd LNK Link Tech Inc LNR Linear Systems Ltd. LNT LANETCO International LNV Lenovo LNX The Linux Foundation LOC Locamation B.V. LOE Loewe Opta GmbH LOG Logicode Technology Inc LOL Litelogic Operations Ltd LPE El-PUSK Co., Ltd. LPI Design Technology LPL LG Philips LSC LifeSize Communications LSD Intersil Corporation LSI Loughborough Sound Images LSJ LSI Japan Company Ltd LSL Logical Solutions LSP Lightspace Technologies LSY LSI Systems Inc LTC Labtec Inc LTI Jongshine Tech Inc LTK Lucidity Technology Company Ltd LTN Litronic Inc LTS LTS Scale LLC LTV Leitch Technology International Inc. LTW Lightware, Inc LUC Lucent Technologies LUM Lumagen, Inc. LUX Luxxell Research Inc LVI LVI Low Vision International AB LWC Labway Corporation LWR Lightware Visual Engineering LWW Lanier Worldwide LXC LXCO Technologies AG LXN Luxeon LXS ELEA CardWare LZX Lightwell Company Ltd MAC MAC System Company Ltd MAD Xedia Corporation MAE Maestro Pty Ltd MAG MAG InnoVision MAI Mutoh America Inc MAL Meridian Audio Ltd MAN LGIC MAS Mass Inc. MAT Panasonic Connect Co.,Ltd. MAX Rogen Tech Distribution Inc MAY Maynard Electronics MAZ MAZeT GmbH MBC MBC MBD Microbus PLC MBM Marshall Electronics MBV Moreton Bay MCA American Nuclear Systems Inc MCC Micro Industries MCD McDATA Corporation MCE Metz-Werke GmbH & Co KG MCG Motorola Computer Group MCI Micronics Computers MCJ Medicaroid Corporation MCL Motorola Communications Israel MCM Metricom Inc MCN Micron Electronics Inc MCO Motion Computing Inc. MCP Magni Systems Inc MCQ Mat's Computers MCR Marina Communicaitons MCS Micro Computer Systems MCT Microtec MCX Millson Custom Solutions Inc. MDA Media4 Inc MDC Midori Electronics MDD MODIS MDF MILDEF AB MDG Madge Networks MDI Micro Design Inc MDK Mediatek Corporation MDO Panasonic MDR Medar Inc MDS Micro Display Systems Inc MDT Magus Data Tech MDV MET Development Inc MDX MicroDatec GmbH MDY Microdyne Inc MEC Mega System Technologies Inc MED Messeltronik Dresden GmbH MEE Mitsubishi Electric Engineering Co., Ltd. MEG Abeam Tech Ltd. MEI Panasonic Industry Company MEJ Mac-Eight Co., LTD. MEK Mediaedge Corporation MEL Mitsubishi Electric Corporation MEN MEN Mikroelectronik Nueruberg GmbH MEP Meld Technology MEQ Matelect Ltd. MET Metheus Corporation MEU MPL AG, Elektronik-Unternehmen MEX MSC Vertriebs GmbH MFG MicroField Graphics Inc MFI Micro Firmware MFR MediaFire Corp. MGA Mega System Technologies, Inc. MGC Mentor Graphics Corporation MGE Schneider Electric S.A. MGL M-G Technology Ltd MGT Megatech R & D Company MHQ Moxa Inc. MIC Micom Communications Inc MID miro Displays MII Mitec Inc MIL Marconi Instruments Ltd MIM Mimio – A Newell Rubbermaid Company MIN Minicom Digital Signage MIP micronpc.com MIR Miro Computer Prod. MIS Modular Industrial Solutions Inc MIT MCM Industrial Technology GmbH MIV MicroImage Video Systems MJI MARANTZ JAPAN, INC. MJS MJS Designs MKC Media Tek Inc. MKS MK Seiko Co., Ltd. MKT MICROTEK Inc. MKV Trtheim Technology MLC MILCOTS MLD Deep Video Imaging Ltd MLG Micrologica AG MLI McIntosh Laboratory Inc. MLL Millogic Ltd. MLM Millennium Engineering Inc MLN Mark Levinson MLP Magic Leap MLS Milestone EPE MLT Wanlida Group Co., Ltd. MLX Mylex Corporation MMA Micromedia AG MMD Micromed Biotecnologia Ltd MMF Minnesota Mining and Manufacturing MMI Multimax MMM Electronic Measurements MMN MiniMan Inc MMS MMS Electronics MMT MIMO Monitors MNC Mini Micro Methods Ltd MNI Marseille, Inc. MNL Monorail Inc MNP Microcom MOC Matrix Orbital Corporation MOD Modular Technology MOM Momentum Data Systems MOS Moses Corporation MOT Motorola UDS MPC M-Pact Inc MPI Mediatrix Peripherals Inc MPJ Microlab MPL Maple Research Inst. Company Ltd MPN Mainpine Limited MPS mps Software GmbH MPV Megapixel Visual Realty MPX Micropix Technologies, Ltd. MQP MultiQ Products AB MRA Miranda Technologies Inc MRC Marconi Simulation & Ty-Coch Way Training MRD MicroDisplay Corporation MRG Nreal MRK Maruko & Company Ltd MRL Miratel MRO Medikro Oy MRT Merging Technologies MSA Micro Systemation AB MSC Mouse Systems Corporation MSD Datenerfassungs- und Informationssysteme MSF M-Systems Flash Disk Pioneers MSG MSI GmbH MSH Microsoft MSI Microstep MSK Megasoft Inc MSL MicroSlate Inc. MSM Advanced Digital Systems MSP Mistral Solutions [P] Ltd. MSR MASPRO DENKOH Corp. MST MS Telematica MSU motorola MSV Mosgi Corporation MSX Micomsoft Co., Ltd. MSY MicroTouch Systems Inc MTA Meta Watch Ltd MTB Media Technologies Ltd. MTC Mars-Tech Corporation MTD MindTech Display Co. Ltd MTE MediaTec GmbH MTH Micro-Tech Hearing Instruments MTI MaxCom Technical Inc MTJ MicroTechnica Co.,Ltd. MTK Microtek International Inc. MTL Mitel Corporation MTM Motium MTN Mtron Storage Technology Co., Ltd. MTR Mitron computer Inc MTS Multi-Tech Systems MTU Mark of the Unicorn Inc MTX Matrox MUD Multi-Dimension Institute MUK Mainpine Limited MVD Microvitec PLC MVI Media Vision Inc MVM SOBO VISION MVN Meta Company MVR MediCapture, Inc. MVS Microvision MVX COM 1 MWI Multiwave Innovation Pte Ltd MWR mware MWY Microway Inc MXD MaxData Computer GmbH & Co.KG MXI Macronix Inc MXL Hitachi Maxell, Ltd. MXM C&T Solution Inc. MXP Maxpeed Corporation MXT Maxtech Corporation MXV MaxVision Corporation MYA Monydata MYR Myriad Solutions Ltd MYX Micronyx Inc NAC Ncast Corporation NAD NAD Electronics NAF NAFASAE INDIA Pvt. Ltd NAK Nakano Engineering Co.,Ltd. NAL Network Alchemy NAT NaturalPoint Inc. NAV Navigation Corporation NAX Naxos Tecnologia NBL N*Able Technologies Inc NBS National Key Lab. on ISN NBT NingBo Bestwinning Technology CO., Ltd NCA Nixdorf Company NCC NCR Corporation NCE Norcent Technology, Inc. NCI NewCom Inc NCL NetComm Ltd NCP Najing CEC Panda FPD Technology CO. ltd NCR NCR Electronics NCS Northgate Computer Systems NCT NEC CustomTechnica, Ltd. NCV NewCoSemi (Beijing) Technology CO.,Ltd. NDC National DataComm Corporaiton NDF NDF Special Light Products B.V. NDI National Display Systems NDK Naitoh Densei CO., LTD. NDL Network Designers NDS Nokia Data NEC NEC Corporation NEO NEO TELECOM CO.,LTD. NES INNES NET Mettler Toledo NEU NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA NEX Nexgen Mediatech Inc., NFC BTC Korea Co., Ltd NFS Number Five Software NGC Network General NGS A D S Exports NHC New H3C Technology Co., Ltd. NHT Vinci Labs NIC National Instruments Corporation NIS Nissei Electric Company NIT Network Info Technology NIX Seanix Technology Inc NLC Next Level Communications NME Navico, Inc. NMP Nokia Mobile Phones NMS Natural Micro System NMV NEC-Mitsubishi Electric Visual Systems Corporation NMX Neomagic NNC NNC NOD 3NOD Digital Technology Co. Ltd. NOE NordicEye AB NOI North Invent A/S NOK Nokia Display Products NOR Norand Corporation NOT Not Limited Inc NPA Arvanics NPI Network Peripherals Inc NRI Noritake Itron Corporation NRL U.S. Naval Research Lab NRT Beijing Northern Radiantelecom Co. NRV Taugagreining hf NSA NeuroSky, Inc. NSC National Semiconductor Corporation NSI NISSEI ELECTRIC CO.,LTD NSP Nspire System Inc. NSS Newport Systems Solutions NST Network Security Technology Co NTC NeoTech S.R.L NTI New Tech Int'l Company NTK NewTek NTL National Transcomm. Ltd NTN Nuvoton Technology Corporation NTR N-trig Innovative Technologies, Inc. NTS Nits Technology Inc. NTT NTT Advanced Technology Corporation NTW Networth Inc NTX Netaccess Inc NUG NU Technology, Inc. NUI NU Inc. NVC NetVision Corporation NVD Nvidia NVI NuVision US, Inc. NVL Novell Inc NVO Netvio Ltd. NVR NOLO CO., LTD. NVT Navatek Engineering Corporation NWC NW Computer Engineering NWL Newline Interactive Inc. NWP NovaWeb Technologies Inc NWS Newisys, Inc. NXC NextCom K.K. NXG Nexgen NXP NXP Semiconductors bv. NXQ Nexiq Technologies, Inc. NXR Nextorage Corporation NXS Technology Nexus Secure Open Systems AB NXT NZXT (PNP same EDID)_ NYC Nakayo Relecommunications, Inc. OAK Oak Tech Inc OAS Oasys Technology Company OBS Optibase Technologies OCD Macraigor Systems Inc OCN Olfan OCS Open Connect Solutions ODM ODME Inc. ODR Odrac OEC ORION ELECTRIC CO.,LTD OEI Optum Engineering Inc. OFI Jiangxi Jinghao Optical Co., Ltd. OHW M-Labs Limited OIC Option Industrial Computers OIM Option International OIN Option International OKI OKI Electric Industrial Company Ltd OLC Olicom A/S OLD Olidata S.p.A. OLI Olivetti OLT Olitec S.A. OLV Olitec S.A. OLY OLYMPUS CORPORATION OMC OBJIX Multimedia Corporation OMN Omnitel OMR Omron Corporation ONE Oneac Corporation ONK ONKYO Corporation ONL OnLive, Inc ONS On Systems Inc ONW OPEN Networks Ltd ONX SOMELEC Z.I. Du Vert Galanta OOS OSRAM OPC Opcode Inc OPI D.N.S. Corporation OPP OPPO Digital, Inc. OPT OPTi Inc OPV Optivision Inc OQI Oksori Company Ltd ORG ORGA Kartensysteme GmbH ORI OSR Open Systems Resources, Inc. ORN ORION ELECTRIC CO., LTD. OSA OSAKA Micro Computer, Inc. OSD Optical Systems Design Pty Ltd OSI Open Stack, Inc. OSP OPTI-UPS Corporation OSR Oksori Company Ltd OTB outsidetheboxstuff.com OTI Orchid Technology OTK OmniTek OTM Optoma Corporation OTT OPTO22, Inc. OUK OUK Company Ltd OVR Oculus VR, Inc. OWL Mediacom Technologies Pte Ltd OXU Oxus Research S.A. OYO Shadow Systems OZC OZ Corporation OZD OZO Co.Ltd OZO Tribe Computer Works Inc PAC Pacific Avionics Corporation PAD Promotion and Display Technology Ltd. PAE PreSonus Audio Electronics PAK Many CNC System Co., Ltd. PAM Peter Antesberger Messtechnik PAN The Panda Project PAR Parallan Comp Inc PBI Pitney Bowes PBL Packard Bell Electronics PBN Packard Bell NEC PBV Pitney Bowes PCA Philips BU Add On Card PCB OCTAL S.A. PCC PowerCom Technology Company Ltd PCG First Industrial Computer Inc PCI Pioneer Computer Inc PCK PCBANK21 PCL pentel.co.,ltd PCM PCM Systems Corporation PCO Performance Concepts Inc., PCP Procomp USA Inc PCS TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION PCT PC-Tel Inc PCW Pacific CommWare Inc PCX PC Xperten PDM Psion Dacom Plc. PDN AT&T Paradyne PDR Pure Data Inc PDS PD Systems International Ltd PDT PDTS - Prozessdatentechnik und Systeme PDV Prodrive B.V. PEC POTRANS Electrical Corp. PEG Pegatron Corporation PEI PEI Electronics Inc PEL Primax Electric Ltd PEN Interactive Computer Products Inc PEP Peppercon AG PER Perceptive Signal Technologies PET Practical Electronic Tools PFT Telia ProSoft AB PGI PACSGEAR, Inc. PGM Paradigm Advanced Research Centre PGP propagamma kommunikation PGS Princeton Graphic Systems PHC Pijnenburg Beheer N.V. PHE Philips Medical Systems Boeblingen GmbH PHI DO NOT USE - PHI PHL Philips Consumer Electronics Company PHO Photonics Systems Inc. PHS Philips Communication Systems PHY Phylon Communications PIC Picturall Ltd. PIE Pacific Image Electronics Company Ltd PIM Prism, LLC PIO Pioneer Electronic Corporation PIR Pico Technology Inc. PIS TECNART CO.,LTD. PIX Pixie Tech Inc PJA Projecta PJD Projectiondesign AS PJT Pan Jit International Inc. PKA Acco UK Ltd. PLC Pro-Log Corporation PLF Panasonic Avionics Corporation PLM PROLINK Microsystems Corp. PLT PT Hartono Istana Teknologi PLV PLUS Vision Corp. PLX Parallax Graphics PLY Polycom Inc. PMC PMC Consumer Electronics Ltd PMD TDK USA Corporation PMM Point Multimedia System PMS Pabian Embedded Systems PMT Promate Electronic Co., Ltd. PMX Photomatrix PNG Microsoft PNL Panelview, Inc. PNP Microsoft PNR Planar Systems, Inc. PNS PanaScope PNT HOYA Corporation PENTAX Lifecare Division PNX Phoenix Technologies, Ltd. POL PolyComp (PTY) Ltd. PON Perpetual Technologies, LLC POR Portalis LC POS Positivo Tecnologia S.A. POT Parrot PPC Phoenixtec Power Company Ltd PPD MEPhI PPI Practical Peripherals PPM Clinton Electronics Corp. PPP Purup Prepress AS PPR PicPro PPX Perceptive Pixel Inc. PQI Pixel Qi PRA PRO/AUTOMATION PRC PerComm PRD Praim S.R.L. PRF Schneider Electric Japan Holdings, Ltd. PRG The Phoenix Research Group Inc PRI Priva Hortimation BV PRM Prometheus PRO Proteon PRP UEFI Forum PRS Leutron Vision PRT Parade Technologies, Ltd. PRX Proxima Corporation PSA Advanced Signal Processing Technologies PSC Philips Semiconductors PSD Peus-Systems GmbH PSE Practical Solutions Pte., Ltd. PSI PSI-Perceptive Solutions Inc PSL Perle Systems Limited PSM Prosum PST Global Data SA PSY Prodea Systems Inc. PTA PAR Tech Inc. PTC PS Technology Corporation PTG Cipher Systems Inc PTH Pathlight Technology Inc PTI Promise Technology Inc PTL Pantel Inc PTS Plain Tree Systems Inc PTW DO NOT USE - PTW PTX Printronix LLC PUL Pulse-Eight Ltd PVC DO NOT USE - PVC PVG Proview Global Co., Ltd PVI Prime view international Co., Ltd PVM Penta Studiotechnik GmbH PVN Pixel Vision PVP Klos Technologies, Inc. PVR Pimax Tech. CO., LTD PXC Phoenix Contact PXE PIXELA CORPORATION PXL The Moving Pixel Company PXM Proxim Inc PXN PixelNext Inc QCC QuakeCom Company Ltd QCH Metronics Inc QCI Quanta Computer Inc QCK Quick Corporation QCL Quadrant Components Inc QCP Qualcomm Inc QDI Quantum Data Incorporated QDL QD Laser, Inc. QDM Quadram QDS Quanta Display Inc. QFF Padix Co., Inc. QFI Quickflex, Inc QLC Q-Logic QQQ Chuomusen Co., Ltd. QSC QSC, LLC QSI Quantum Solutions, Inc. QTD Quantum 3D Inc QTH Questech Ltd QTI Quicknet Technologies Inc QTM Quantum QTR Qtronix Corporation QUA Quatographic AG QUE Questra Consulting QVU Quartics RAC Racore Computer Products Inc RAD Radisys Corporation RAI Rockwell Automation/Intecolor RAN Rancho Tech Inc RAR Raritan, Inc. RAS RAScom Inc RAT Rent-A-Tech RAY Raylar Design, Inc. RCE Parc d'Activite des Bellevues RCH Reach Technology Inc RCI RC International RCN Radio Consult SRL RCO Rockwell Collins RDI Rainbow Displays, Inc. RDL Riedel Communications Canada Inc. RDM Tremon Enterprises Company Ltd RDN RADIODATA GmbH RDS Radius Inc REA Real D REC ReCom RED Research Electronics Development Inc REF Reflectivity, Inc. REH Rehan Electronics Ltd. REL Reliance Electric Ind Corporation REM SCI Systems Inc. REN Renesas Technology Corp. RES ResMed Pty Ltd RET Resonance Technology, Inc. REV Revolution Display, Inc. REX RATOC Systems, Inc. RFI RAFI GmbH & Co. KG RFX Redfox Technologies Inc. RGB RGB Spectrum RGL Robertson Geologging Ltd RHD RightHand Technologies RHM Rohm Company Ltd RHT Red Hat, Inc. RIC RICOH COMPANY, LTD. RII Racal Interlan Inc RIO Rios Systems Company Ltd RIT Ritech Inc RIV Rivulet Communications RJA Roland Corporation RJS Advanced Engineering RKC Reakin Technolohy Corporation RLD MEPCO RLN RadioLAN Inc RMC Raritan Computer, Inc RMP Research Machines RMS Shenzhen Ramos Digital Technology Co., Ltd RMT Roper Mobile RNB Rainbow Technologies ROB Robust Electronics GmbH ROH Rohm Co., Ltd. ROK Rockwell International ROP Roper International Ltd ROS Rohde & Schwarz RPI RoomPro Technologies RPT R.P.T.Intergroups RRI Radicom Research Inc RSC PhotoTelesis RSH ADC-Centre RSI Rampage Systems Inc RSN Radiospire Networks, Inc. RSQ R Squared RSR Zhong Shan City Richsound Electronic Industrial Ltd. RSS Rockwell Semiconductor Systems RSV Ross Video Ltd RSX Rapid Tech Corporation RTC Relia Technologies RTI Rancho Tech Inc RTK DO NOT USE - RTK RTL Realtek Semiconductor Company Ltd RTS Raintree Systems RUN RUNCO International RUP Ups Manufactoring s.r.l. RVC RSI Systems Inc RVI Realvision Inc RVL Reveal Computer Prod RWC Red Wing Corporation RXT Tectona SoftSolutions (P) Ltd., RZR Razer Taiwan Co. Ltd. RZS Rozsnyó, s.r.o. SAA Sanritz Automation Co.,Ltd. SAE Saab Aerotech SAG Sedlbauer SAI Sage Inc SAK Saitek Ltd SAM Samsung Electric Company SAN Sanyo Electric Co.,Ltd. SAS Stores Automated Systems Inc SAT Shuttle Tech SBC Shanghai Bell Telephone Equip Mfg Co SBD Softbed - Consulting & Development Ltd SBI SMART Technologies Inc. SBS SBS-or Industrial Computers GmbH SBT Senseboard Technologies AB SCA Schneider Consumer Group SCB SeeCubic B.V. SCC SORD Computer Corporation SCD Sanyo Electric Company Ltd SCE Sun Corporation SCG Seco S.p.A. SCH Schlumberger Cards SCI System Craft SCL Sigmacom Co., Ltd. SCM SCM Microsystems Inc SCN Scanport, Inc. SCO SORCUS Computer GmbH SCP Scriptel Corporation SCR Systran Corporation SCS Nanomach Anstalt SCT Smart Card Technology SCX Socionext Inc. SDA SAT (Societe Anonyme) SDD Intrada-SDD Ltd SDE Sherwood Digital Electronics Corporation SDF SODIFF E&T CO., Ltd. SDH Communications Specialies, Inc. SDI Samtron Displays Inc SDK SAIT-Devlonics SDR SDR Systems SDS SunRiver Data System SDT Siemens AG SDX SDX Business Systems Ltd SEA Seanix Technology Inc. SEB system elektronik GmbH SEC Seiko Epson Corporation SEE SeeColor Corporation SEG DO NOT USE - SEG SEI Seitz & Associates Inc SEL Way2Call Communications SEM Samsung Electronics Company Ltd SEN Sencore SEO SEOS Ltd SEP SEP Eletronica Ltda. SER Sony Ericsson Mobile Communications Inc. SES Session Control LLC SET SendTek Corporation SFL Shiftall Inc. SFM TORNADO Company SFT Mikroforum Ring 3 SGC Spectragraphics Corporation SGD Sigma Designs, Inc. SGE Kansai Electric Company Ltd SGI Scan Group Ltd SGL Super Gate Technology Company Ltd SGM SAGEM SGO Logos Design A/S SGT Stargate Technology SGW Shanghai Guowei Science and Technology Co., Ltd. SGX Silicon Graphics Inc SGZ Systec Computer GmbH SHC ShibaSoku Co., Ltd. SHG Soft & Hardware development Goldammer GmbH SHI Jiangsu Shinco Electronic Group Co., Ltd SHP Sharp Corporation SHR Digital Discovery SHT Shin Ho Tech SIA SIEMENS AG SIB Sanyo Electric Company Ltd SIC Sysmate Corporation SID Seiko Instruments Information Devices Inc SIE Siemens SIG Sigma Designs Inc SII Silicon Image, Inc. SIL Silicon Laboratories, Inc SIM S3 Inc SIN Singular Technology Co., Ltd. SIR Sirius Technologies Pty Ltd SIS Silicon Integrated Systems Corporation SIT Sitintel SIU Seiko Instruments USA Inc SIX Zuniq Data Corporation SJE Sejin Electron Inc SKD Schneider & Koch SKG Shenzhen KTC Technology Group SKI LLC SKTB “SKIT” SKM Guangzhou Teclast Information Technology Limited SKT Samsung Electro-Mechanics Company Ltd SKW Skyworth SKY SKYDATA S.P.A. SLA Systeme Lauer GmbH&Co KG SLB Shlumberger Ltd SLC Syslogic Datentechnik AG SLF StarLeaf SLH Silicon Library Inc. SLI Symbios Logic Inc SLK Silitek Corporation SLM Solomon Technology Corporation SLR Schlumberger Technology Corporate SLS Schnick-Schnack-Systems GmbH SLT Salt Internatioinal Corp. SLX Specialix SMA SMART Modular Technologies SMB Schlumberger SMC Standard Microsystems Corporation SME Sysmate Company SMI SpaceLabs Medical Inc SMK SMK CORPORATION SML Sumitomo Metal Industries, Ltd. SMM Shark Multimedia Inc SMO STMicroelectronics SMP Simple Computing SMR B.& V. s.r.l. SMS Silicom Multimedia Systems Inc SMT Silcom Manufacturing Tech Inc SNC Sentronic International Corp. SNI Siemens Microdesign GmbH SNK S&K Electronics SNN SUNNY ELEKTRONIK SNO SINOSUN TECHNOLOGY CO., LTD SNP Siemens Nixdorf Info Systems SNS Cirtech (UK) Ltd SNT SuperNet Inc SNV SONOVE GmbH SNW Snell & Wilcox SNX Sonix Comm. Ltd SNY Sony SOC Santec Corporation SOI Silicon Optix Corporation SOL Solitron Technologies Inc SON Sony SOR Sorcus Computer GmbH SOT Sotec Company Ltd SOY SOYO Group, Inc SPC SpinCore Technologies, Inc SPE SPEA Software AG SPH G&W Instruments GmbH SPI SPACE-I Co., Ltd. SPK SpeakerCraft SPL Smart Silicon Systems Pty Ltd SPN Sapience Corporation SPO SAMPO CORPORATION SPR pmns GmbH SPS Synopsys Inc SPT Sceptre Tech Inc SPU SIM2 Multimedia S.P.A. SPX Simplex Time Recorder Co. SQT Sequent Computer Systems Inc SRC Integrated Tech Express Inc SRD Setred SRF Surf Communication Solutions Ltd SRG Intuitive Surgical, Inc. SRS SR-Systems e.K. SRT SeeReal Technologies GmbH SSC Sierra Semiconductor Inc SSD FlightSafety International SSE Samsung Electronic Co. SSG Steelseries ApS SSI S-S Technology Inc SSJ Sankyo Seiki Mfg.co., Ltd SSL Shenzhen South-Top Computer Co., Ltd. SSP Spectrum Signal Proecessing Inc SSS S3 Inc SST SystemSoft Corporation STA ST Electronics Systems Assembly Pte Ltd STB STB Systems Inc STC STAC Electronics STD STD Computer Inc STE SII Ido-Tsushin Inc STF Starflight Electronics STG StereoGraphics Corp. STH Semtech Corporation STI Smart Tech Inc STK SANTAK CORP. STL SigmaTel Inc STM SGS Thomson Microelectronics STN Samsung Electronics America STO Stollmann E+V GmbH STP StreamPlay Ltd STQ Synthetel Corporation STR Starlight Networks Inc STS SITECSYSTEM CO., LTD. STT Star Paging Telecom Tech (Shenzhen) Co. Ltd. STU Sentelic Corporation STV Beijing Guochengwantong Information Technology Co., Ltd. STW Starwin Inc. STX ST-Ericsson STY SDS Technologies SUB Subspace Comm. Inc SUM Summagraphics Corporation SUN Sun Electronics Corporation SUP Supra Corporation SUR Surenam Computer Corporation SVA SGEG SVC Intellix Corp. SVD SVD Computer SVI Sun Microsystems SVR Sensics, Inc. SVS SVSI SVT SEVIT Co., Ltd. SWC Software Café SWI Sierra Wireless Inc. SWL Sharedware Ltd SWO Guangzhou Shirui Electronics Co., Ltd. SWS Static SWT Software Technologies Group,Inc. SXB Syntax-Brillian SXD Silex technology, Inc. SXG SELEX GALILEO SXI Silex Inside SXL SolutionInside SXT SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD. SYC Sysmic SYE SY Electronics Ltd SYK Stryker Communications SYL Sylvania Computer Products SYM Symicron Computer Communications Ltd. SYN Synaptics Inc SYP SYPRO Co Ltd SYS Sysgration Ltd SYT Seyeon Tech Company Ltd SYV SYVAX Inc SYX Prime Systems, Inc. SZM Shenzhen MTC Co., Ltd TAA Tandberg TAB Todos Data System AB TAG Teles AG TAI Toshiba America Info Systems Inc TAM Tamura Seisakusyo Ltd TAS Taskit Rechnertechnik GmbH TAT Teleliaison Inc TAV Thales Avionics TAX Taxan (Europe) Ltd TBB Triple S Engineering Inc TBC Turbo Communication, Inc TBS Turtle Beach System TCC Tandon Corporation TCD Taicom Data Systems Co., Ltd. TCE Century Corporation TCF Televic Conference TCH Interaction Systems, Inc TCI Tulip Computers Int'l B.V. TCJ TEAC America Inc TCL Technical Concepts Ltd TCM 3Com Corporation TCN Tecnetics (PTY) Ltd TCO Thomas-Conrad Corporation TCR Thomson Consumer Electronics TCS Tatung Company of America Inc TCT Telecom Technology Centre Co. Ltd. TCX FREEMARS Heavy Industries TDC Teradici TDD Tandberg Data Display AS TDG Six15 Technologies TDM Tandem Computer Europe Inc TDP 3D Perception TDS Tri-Data Systems Inc TDT TDT TDV TDVision Systems, Inc. TDY Tandy Electronics TEA TEAC System Corporation TEC Tecmar Inc TEK Tektronix Inc TEL Promotion and Display Technology Ltd. TEN Tencent TER TerraTec Electronic GmbH TET TETRADYNE CO., LTD. TEV Televés, S.A. TEZ Tech Source Inc. TGC Toshiba Global Commerce Solutions, Inc. TGI TriGem Computer Inc TGM TriGem Computer,Inc. TGS Torus Systems Ltd TGV Grass Valley Germany GmbH TGW TECHNOGYM S.p.A. THN Thundercom Holdings Sdn. Bhd. TIC Trigem KinfoComm TIL Technical Illusions Inc. TIP TIPTEL AG TIV OOO Technoinvest TIX Tixi.Com GmbH TKC Taiko Electric Works.LTD TKG Tek Gear TKN Teknor Microsystem Inc TKO TouchKo, Inc. TKS TimeKeeping Systems, Inc. TLA Ferrari Electronic GmbH TLD Telindus TLE Zhejiang Tianle Digital Electric Co., Ltd. TLF Teleforce.,co,ltd TLI TOSHIBA TELI CORPORATION TLK Telelink AG TLL Thinklogical TLN Techlogix Networx TLS Teleste Educational OY TLT Dai Telecom S.p.A. TLV S3 Inc TLX Telxon Corporation TLY Truly Semiconductors Ltd. TMA Tianma Microelectronics Ltd. TMC Techmedia Computer Systems Corporation TME AT&T Microelectronics TMI Texas Microsystem TMM Time Management, Inc. TMO Terumo Corporation TMR Taicom International Inc TMS Trident Microsystems Ltd TMT T-Metrics Inc. TMX Thermotrex Corporation TNC TNC Industrial Company Ltd TNJ DO NOT USE - TNJ TNM TECNIMAGEN SA TNY Tennyson Tech Pty Ltd TOE TOEI Electronics Co., Ltd. TOG The OPEN Group TOL TCL Corporation TOM Ceton Corporation TON TONNA TOP Orion Communications Co., Ltd. TOS Dynabook Inc. TOU Touchstone Technology TPC Touch Panel Systems Corporation TPD Times (Shanghai) Computer Co., Ltd. TPE Technology Power Enterprises Inc TPJ Junnila TPK TOPRE CORPORATION TPR Topro Technology Inc TPS Teleprocessing Systeme GmbH TPT Thruput Ltd TPV Top Victory Electronics ( Fujian ) Company Ltd TPZ Ypoaz Systems Inc TRA TriTech Microelectronics International TRB Triumph Board a.s. TRC Trioc AB TRD Trident Microsystem Inc TRE Tremetrics TRI Tricord Systems TRL Royal Information TRM Tekram Technology Company Ltd TRN Datacommunicatie Tron B.V. TRP TRAPEZE GROUP TRS Torus Systems Ltd TRT Tritec Electronic AG TRU Aashima Technology B.V. TRV Trivisio Prototyping GmbH TRX Trex Enterprises TSB Toshiba America Info Systems Inc TSC Sanyo Electric Company Ltd TSD TechniSat Digital GmbH TSE Tottori Sanyo Electric TSF Racal-Airtech Software Forge Ltd TSG The Software Group Ltd TSH ELAN MICROELECTRONICS CORPORATION TSI TeleVideo Systems TSL Tottori SANYO Electric Co., Ltd. TSP U.S. Navy TST Transtream Inc TSV TRANSVIDEO TSW VRSHOW Technology Limited TSY TouchSystems TTA Topson Technology Co., Ltd. TTB National Semiconductor Japan Ltd TTC Telecommunications Techniques Corporation TTE TTE, Inc. TTI Trenton Terminals Inc TTK Totoku Electric Company Ltd TTL 2-Tel B.V TTP Toshiba Corporation TTR Hubei Century Joint Innovation Technology Co.Ltd TTS TechnoTrend Systemtechnik GmbH TTX Taitex Corporation TTY TRIDELITY Display Solutions GmbH TUA T+A elektroakustik GmbH TUT Tut Systems TVD Tecnovision TVI Truevision TVL Total Vision LTD TVM Taiwan Video & Monitor Corporation TVO TV One Ltd TVR TV Interactive Corporation TVS TVS Electronics Limited TVV TV1 GmbH TWA Tidewater Association TWE Kontron Electronik TWH Twinhead International Corporation TWI Easytel oy TWK TOWITOKO electronics GmbH TWX TEKWorx Limited TXL Trixel Ltd TXN Texas Insturments TXT Textron Defense System TYN Tyan Computer Corporation UAS Ultima Associates Pte Ltd UBI Ungermann-Bass Inc UBL Ubinetics Ltd. UBU Canonical Ltd. UDN Uniden Corporation UEC Ultima Electronics Corporation UEG Elitegroup Computer Systems Company Ltd UEI Universal Electronics Inc UET Universal Empowering Technologies UFG UNIGRAF-USA UFO UFO Systems Inc UHB XOCECO UIC Uniform Industrial Corporation UJR Ueda Japan Radio Co., Ltd. ULT Ultra Network Tech UMC United Microelectr Corporation UMG Umezawa Giken Co.,Ltd UMM Universal Multimedia UMT UltiMachine UNA Unisys DSD UNB Unisys Corporation UNC Unisys Corporation UND Unisys Corporation UNE Unisys Corporation UNF Unisys Corporation UNI Uniform Industry Corp. UNM Unisys Corporation UNO Unisys Corporation UNP Unitop UNS Unisys Corporation UNT Unisys Corporation UNY Unicate UPP UPPI UPS Systems Enhancement URD Video Computer S.p.A. USA Utimaco Safeware AG USD U.S. Digital Corporation USE U. S. Electronics Inc. USI Universal Scientific Industrial Co., Ltd. USR U.S. Robotics Inc UTC Unicompute Technology Co., Ltd. UTD Up to Date Tech UWC Uniwill Computer Corp. VAD Vaddio, LLC VAI VAIO Corporation VAL Valence Computing Corporation VAR Varian Australia Pty Ltd VAT VADATECH INC VAV aviica VBR VBrick Systems Inc. VBT Valley Board Ltda VCC Virtual Computer Corporation VCE VARCem VCI VistaCom Inc VCJ Victor Company of Japan, Limited VCM Vector Magnetics, LLC VCX VCONEX VDA Victor Data Systems VDC VDC Display Systems VDM Vadem VDO Video & Display Oriented Corporation VDS Vidisys GmbH & Company VDT Viditec, Inc. VEC Vector Informatik GmbH VEK Vektrex VES Vestel Elektronik Sanayi ve Ticaret A. S. VFI VeriFone Inc VHI Macrocad Development Inc. VIA VIA Tech Inc VIB Tatung UK Ltd VIC Victron B.V. VID Ingram Macrotron Germany VIK Viking Connectors VIM Via Mons Ltd. VIN Vine Micros Ltd VIO Zake IP Holdings LLC (3B tech) VIR Visual Interface, Inc VIS Visioneer VIT Visitech AS VIZ VIZIO, Inc VLB ValleyBoard Ltda. VLC VersaLogic Corporation VLK Vislink International Ltd VLM LENOVO BEIJING CO. LTD. VLT VideoLan Technologies VLV Valve Corporation VMI Vermont Microsystems VML Vine Micros Limited VMW VMware Inc., VNC Vinca Corporation VNX Venetex Corporation VOB MaxData Computer AG VPI Video Products Inc VPR Best Buy VPX VPixx Technologies Inc. VQ@ Vision Quest VRC Virtual Resources Corporation VRG VRgineers, Inc. VRM VRmagic Holding AG VRS VRstudios, Inc. VRT Varjo Technologies VSC ViewSonic Corporation VSD 3M VSI VideoServer VSN Ingram Macrotron VSP Vision Systems GmbH VSR V-Star Electronics Inc. VTB Videotechnik Breithaupt VTC VTel Corporation VTG Voice Technologies Group Inc VTI VLSI Tech Inc VTK Viewteck Co., Ltd. VTL Vivid Technology Pte Ltd VTM Miltope Corporation VTN VIDEOTRON CORP. VTS VTech Computers Ltd VTV VATIV Technologies VTX Vestax Corporation VUT Vutrix (UK) Ltd VWB Vweb Corp. WAC Wacom Tech WAL Wave Access WAN DO NOT USE - WAN WAV Wavephore WBN MicroSoftWare WBS WB Systemtechnik GmbH WCI Wisecom Inc WCS Woodwind Communications Systems Inc WDC Western Digital WDE Westinghouse Digital Electronics WEB WebGear Inc WEC Winbond Electronics Corporation WEL W-DEV WEY WEY Design AG WHI Whistle Communications WII Innoware Inc WIL WIPRO Information Technology Ltd WIN Wintop Technology Inc WIP Wipro Infotech WKH Uni-Take Int'l Inc. WLD Wildfire Communications Inc WLF WOLF Advanced Technology WMI Weidmuller Interface GmbH & Co. KG WML Wolfson Microelectronics Ltd WMO Westermo Teleindustri AB WMT Winmate Communication Inc WNI WillNet Inc. WNV Winnov L.P. WNX Diebold Nixdorf Systems GmbH WPA Matsushita Communication Industrial Co., Ltd. WPI Wearnes Peripherals International (Pte) Ltd WRC WiNRADiO Communications WSC CIS Technology Inc WSP Wireless And Smart Products Inc. WST Wistron Corporation WTC ACC Microelectronics WTI WorkStation Tech WTK Wearnes Thakral Pte WTS Restek Electric Company Ltd WVM Wave Systems Corporation WVV WolfVision GmbH WWP Wipotec Wiege- und Positioniersysteme GmbH WWV World Wide Video, Inc. WXT Woxter Technology Co. Ltd WYR WyreStorm Technologies LLC WYS Wyse Technology WYT Wooyoung Image & Information Co.,Ltd. XAC XAC Automation Corp XAD Alpha Data XDM XDM Ltd. XER DO NOT USE - XER XES Extreme Engineering Solutions, Inc. XFG Jan Strapko - FOTO XFO EXFO Electro Optical Engineering XIN Xinex Networks Inc XIO Xiotech Corporation XIR Xirocm Inc XIT Xitel Pty ltd XLX Xilinx, Inc. XMM C3PO S.L. XNT XN Technologies, Inc. XOC DO NOT USE - XOC XQU SHANGHAI SVA-DAV ELECTRONICS CO., LTD XRC Xircom Inc XRO XORO ELECTRONICS (CHENGDU) LIMITED XSN Xscreen AS XST XS Technologies Inc XSY XSYS XTD Icuiti Corporation XTE X2E GmbH XTL Crystal Computer XTN X-10 (USA) Inc XYC Xycotec Computer GmbH XYE Shenzhen Zhuona Technology Co., Ltd. YED Y-E Data Inc YHQ Yokogawa Electric Corporation YHW Exacom SA YMH Yamaha Corporation YOW American Biometric Company ZAN Zandar Technologies plc ZAX Zefiro Acoustics ZAZ ZeeVee, Inc. ZBR Zebra Technologies International, LLC ZBX Zebax Technologies ZCT ZeitControl cardsystems GmbH ZDS Zenith Data Systems ZEN ZENIC Inc. ZGT Zenith Data Systems ZIC Nationz Technologies Inc. ZMC HangZhou ZMCHIVIN ZMT Zalman Tech Co., Ltd. ZMZ Z Microsystems ZNI Zetinet Inc ZNX Znyx Adv. Systems ZOW Zowie Intertainment, Inc ZRN Zoran Corporation ZSE Zenith Data Systems ZTC ZyDAS Technology Corporation ZTE ZTE Corporation ZTI Zoom Telephonics Inc ZTM ZT Group Int'l Inc. ZTT Z3 Technology ZWE Shenzhen Zowee Technology Co., LTD ZYD Zydacron Inc ZYP Zypcom Inc ZYT Zytex Computers ZYX Zyxel ZZZ Boca Research Inc dxvk-0~git20230309.275e645/test/000077500000000000000000000000001440230200600156025ustar00rootroot00000000000000dxvk-0~git20230309.275e645/test/data/000077500000000000000000000000001440230200600165135ustar00rootroot00000000000000dxvk-0~git20230309.275e645/test/data/LICENSE.CC-BY-4.0000066400000000000000000000443401440230200600206200ustar00rootroot00000000000000Attribution 4.0 International ======================================================================= Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. Using Creative Commons Public Licenses Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason--for example, because of any applicable exception or limitation to copyright--then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More_considerations for the public: wiki.creativecommons.org/Considerations_for_licensees ======================================================================= Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. Section 1 -- Definitions. a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. Section 2 -- Scope. a. License grant. 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: a. reproduce and Share the Licensed Material, in whole or in part; and b. produce, reproduce, and Share Adapted Material. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 3. Term. The term of this Public License is specified in Section 6(a). 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a) (4) never produces Adapted Material. 5. Downstream recipients. a. Offer from the Licensor -- Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. b. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). b. Other rights. 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 2. Patent and trademark rights are not licensed under this Public License. 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. Section 3 -- License Conditions. Your exercise of the Licensed Rights is expressly made subject to the following conditions. a. Attribution. 1. If You Share the Licensed Material (including in modified form), You must: a. retain the following if it is supplied by the Licensor with the Licensed Material: i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); ii. a copyright notice; iii. a notice that refers to this Public License; iv. a notice that refers to the disclaimer of warranties; v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; b. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and c. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. Section 4 -- Sui Generis Database Rights. Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. Section 5 -- Disclaimer of Warranties and Limitation of Liability. a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. Section 6 -- Term and Termination. a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 2. upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. Section 7 -- Other Terms and Conditions. a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. Section 8 -- Interpretation. a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. ======================================================================= Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. dxvk-0~git20230309.275e645/test/data/README.md000066400000000000000000000007441440230200600177770ustar00rootroot00000000000000# Test data The following blobs originate from the [linuxhw/EDID] repository and are licensed under the [Creative Commons Attribution 4.0 International][CC-BY-4.0] license: - acer-p1276 - goldstar-ite6604-hdmi - msi-mag321curv-dp - panasonic-mei96a2-dp - samsung-s27a950d-dp - sun-gh19ps-dvi - viewsonic-vp2768-dp The other blobs are under the same license as the rest of the libdisplay-info project. [linuxhw/EDID]: https://github.com/linuxhw/EDID [CC-BY-4.0]: LICENSE.CC-BY-4.0 dxvk-0~git20230309.275e645/test/data/acer-p1276.diff000066400000000000000000000016731440230200600210430ustar00rootroot00000000000000--- ref +++ di @@ -65,23 +65,8 @@ DTD 2: 1366x768 59.789541 Hz 683:384 47.712 kHz 85.500000 MHz Hfront 70 Hsync 143 Hback 213 Hpol P Vfront 3 Vsync 3 Vback 24 Vpol P -Checksum: 0xab Unused space in Extension Block: 105 bytes +Checksum: 0xab ---------------- -Warnings: - -Block 0, Base EDID: - Basic Display Parameters & Features: sRGB is signaled, but the gamma != 2.2. -Block 1, CTA-861 Extension Block: - IT Video Formats are overscanned by default, but normally this should be underscanned. - Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0. - -Failures: - -Block 0, Base EDID: - Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match. -Block 1, CTA-861 Extension Block: - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. - -EDID conformity: FAIL +EDID conformity: PASS dxvk-0~git20230309.275e645/test/data/acer-p1276.edid000066400000000000000000000004001440230200600210230ustar00rootroot00000000000000r>/A\X%S_?π1|E|a|@d@A&062xd P1276 JGG110015900 f!VQ0F3dxvk-0~git20230309.275e645/test/data/acer-p1276.print000066400000000000000000000000721440230200600212570ustar00rootroot00000000000000make: Acer Technologies model: P1276 serial: JGG110015900 dxvk-0~git20230309.275e645/test/data/apple-xdr-dp.diff000066400000000000000000000131731440230200600216470ustar00rootroot00000000000000--- ref +++ di @@ -62,16 +62,13 @@ DTD 6: 3840x2160 47.951737 Hz 16:9 134.696 kHz 528.010000 MHz (699 mm x 393 mm) Hfront 8 Hsync 32 Hback 40 Hpol P Vfront 59 Vsync 8 Vback 582 Vpol N -Checksum: 0x01 Unused space in Extension Block: 58 bytes +Checksum: 0x01 ---------------- Block 2, DisplayID Extension Block: Version: 1.2 - Extension Count: 0 Display Product Type: Extension Section - ContainerID Data Block: - Container ID: dfde542f-1339-444b-ad7d-7071d131bff8 Display Parameters Data Block (0x01): Image size: 699.4 mm x 393.4 mm Display native pixel format: 6016x3384 @@ -81,25 +78,7 @@ Aspect ratio: 1.78 Dynamic bpc native: 12 Dynamic bpc overall: 12 - Vendor-Specific Data Block (0x7f) (Apple), OUI 00-10-FA: - Type: 4, Version: 1 - 00 00 '..' Tiled Display Topology Data Block (0x12): - Capabilities: - Behavior if it is the only tile: Image is scaled to fit the entire tiled display - Behavior if more than one tile and fewer than total number of tiles: Undefined - Tiled display consists of a single physical display enclosure - Num horizontal tiles: 2 Num vertical tiles: 1 - Tile location: 0, 0 - Tile resolution: 3008x3384 - Tiled Display Manufacturer/Vendor ID: APP - Tiled Display Product ID Code: 44591 - Tiled Display Serial Number: 621612546 - Vendor-Specific Data Block (0x7e) (VESA), OUI 3A-02-92: - Data Structure Type: DP - Default Colorspace and EOTF Handling: Native as specified in the Display Parameters DB - Number of Pixels in Hor Pix Cnt Overlapping an Adjacent Panel: 0 - Multi-SST Operation: Not Supported Video Timing Modes Type 1 - Detailed Timings Data Block: DTD: 3840x2160 59.999545 Hz 16:9 134.699 kHz 528.020000 MHz (aspect 16:9, no 3D stereo) Hfront 8 Hsync 32 Hback 40 Hpol P @@ -107,14 +86,12 @@ DTD: 3008x3384 59.999726 Hz 0:0 210.959 kHz 648.910000 MHz (aspect undefined, no 3D stereo) Hfront 8 Hsync 32 Hback 28 Hpol P Vfront 118 Vsync 8 Vback 6 Vpol N - Checksum: 0x8c Checksum: 0x90 ---------------- Block 3, DisplayID Extension Block: Version: 1.2 - Extension Count: 0 Video Timing Modes Type 1 - Detailed Timings Data Block: DTD: 2560x2880 59.999451 Hz 0:0 179.578 kHz 481.270000 MHz (aspect undefined, no 3D stereo) Hfront 8 Hsync 32 Hback 80 Hpol P @@ -131,14 +108,12 @@ DTD: 2560x2880 47.951349 Hz 0:0 179.530 kHz 481.140000 MHz (aspect undefined, no 3D stereo) Hfront 8 Hsync 32 Hback 80 Hpol P Vfront 850 Vsync 8 Vback 6 Vpol N - Checksum: 0x93 Checksum: 0x90 ---------------- Block 4, DisplayID Extension Block: Version: 1.2 - Extension Count: 0 Video Timing Modes Type 1 - Detailed Timings Data Block: DTD: 3008x3384 59.999726 Hz 0:0 210.959 kHz 648.910000 MHz (aspect undefined, no 3D stereo) Hfront 8 Hsync 32 Hback 28 Hpol P @@ -155,14 +130,12 @@ DTD: 3008x3384 47.951701 Hz 0:0 210.940 kHz 648.850000 MHz (aspect undefined, no 3D stereo) Hfront 8 Hsync 32 Hback 28 Hpol P Vfront 1001 Vsync 8 Vback 6 Vpol N - Checksum: 0x7e Checksum: 0x90 ---------------- Block 5, DisplayID Extension Block: Version: 1.2 - Extension Count: 0 Video Timing Modes Type 1 - Detailed Timings Data Block: DTD: 5120x2880 59.999614 Hz 16:9 179.579 kHz 933.810000 MHz (aspect 16:9, no 3D stereo) Hfront 8 Hsync 32 Hback 40 Hpol P @@ -179,14 +152,12 @@ DTD: 5120x2880 47.951594 Hz 16:9 179.531 kHz 933.560000 MHz (aspect 16:9, no 3D stereo) Hfront 8 Hsync 32 Hback 40 Hpol P Vfront 850 Vsync 8 Vback 6 Vpol N - Checksum: 0x0a Checksum: 0x90 ---------------- Block 6, DisplayID Extension Block: Version: 1.2 - Extension Count: 0 Video Timing Modes Type 1 - Detailed Timings Data Block: DTD: 6016x3384 59.999899 Hz 16:9 210.960 kHz 1286.010000 MHz (aspect 16:9, no 3D stereo, preferred) Hfront 8 Hsync 32 Hback 40 Hpol P @@ -203,30 +174,13 @@ DTD: 6016x3384 47.951798 Hz 16:9 210.940 kHz 1285.890000 MHz (aspect 16:9, no 3D stereo) Hfront 8 Hsync 32 Hback 40 Hpol P Vfront 1001 Vsync 8 Vback 6 Vpol N - Checksum: 0xb4 Checksum: 0x90 ---------------- -Warnings: - -Block 1, CTA-861 Extension Block: - Colorimetry Data Block: Set the sRGB colorimetry bit to avoid interop issues. -Block 2, DisplayID Extension Block: - Vendor-Specific Data Block (0x7f) (Apple), OUI 00-10-FA: Expected PNP ID but found OUI. - Failures: -Block 1, CTA-861 Extension Block: - Required 640x480p60 timings are missing in the established timings and the SVD list (VIC 1). - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. Block 2, DisplayID Extension Block: - DisplayID Base Block has no product type. - Expected 0 DisplayID Extension Block, but got 4. - ContainerID Data Block: Use of DisplayID v2.0 tag for DisplayID v1.2. - Vendor-Specific Data Block (0x7f) (Apple), OUI 00-10-FA: Endian-ness (le) of OUI is different than expected (be). - Vendor-Specific Data Block (0x7e) (VESA), OUI 3A-02-92: Use of DisplayID v2.0 tag for DisplayID v1.2. -EDID: - DisplayID: Missing DisplayID Product Identification Data Block. - + Unknown DisplayID Data Block (0x29, length 16) + Unknown DisplayID Data Block (0x7e, length 5) EDID conformity: FAIL dxvk-0~git20230309.275e645/test/data/apple-xdr-dp.edid000066400000000000000000000016001440230200600216340ustar00rootroot00000000000000. %F'xRC&PTBPpU x!BPp !\P9P !ProDisplayXDRk<PpW !=Pp !APp !py)T/9DK}pq1 R^8 xN 7 APP/ %~:(AOoTFz C7 upyd w? pb w? rd w?  w? \N w? _Qpydz C7 up C7 xw C7 B4z C7 t C7 ~pydlO? pblO? rdlO? lO? \NlO? _Q pydXO7 uEO7 xRO7 B4XO7 LO7 dxvk-0~git20230309.275e645/test/data/apple-xdr-dp.print000066400000000000000000000001011440230200600220560ustar00rootroot00000000000000make: Apple Computer Inc model: ProDisplayXDR serial: 0x250D0E02 dxvk-0~git20230309.275e645/test/data/custom-uncommon-cta-vesa.diff000066400000000000000000000052671440230200600242230ustar00rootroot00000000000000--- ref +++ di @@ -58,12 +58,8 @@ Supports YCbCr 4:2:2 Native detailed modes: 0 Video Data Block: - VIC 97: 3840x2160 60.000000 Hz 16:9 135.000 kHz 594.000000 MHz + VIC 97 Audio Data Block: - Linear PCM: - Max channels: 2 - Supported sample rates (kHz): 48 44.1 32 - Supported sample sizes (bits): 24 20 16 Video Capability Data Block: YCbCr quantization: Selectable (via AVI YQ) RGB quantization: Selectable (via AVI Q) @@ -73,54 +69,12 @@ VESA Display Transfer Characteristics Data Block: White transfer characteristics: 6 33 77 129 192 252 348 415 490 598 666 796 873 932 998 1023 VESA Video Display Device Data Block: - Interface Type: DisplayPort 2 channels - Interface Standard Version: 1.1 - Content Protection Support: DPCP - Minimum Clock Frequency: 0 MHz - Maximum Clock Frequency: 0 MHz - Device Native Pixel Format: 2560x1600 - Aspect Ratio: 1.60 - Default Orientation: Landscape - Rotation Capability: Can rotate 90 degrees clockwise - Zero Pixel Location: Upper Left - Scan Direction: Fast Scan is on the Major (Long) Axis and Slow Scan is on the Minor Axis - Subpixel Information: Five sub-pixels, RGB + 2 additional colors - Horizontal and vertical dot/pixel pitch: 0.24 x 0.24 mm - Dithering: Spatial and Temporal - Direct Drive: No - Overdrive not recommended - Deinterlacing: No - Audio Support: Yes - Separate Audio Inputs Provided: No - Audio Input Override: No - Audio Delay: 6 ms - Frame Rate/Mode Conversion: Double Buffering - Frame Rate Range: 60 fps +/- 15 fps - Color Bit Depth: 8 @ interface, 8 @ display - Additional Primary Chromaticities: - Primary 4: 0.1455, 0.2890 - Primary 5: 0.4921, 0.4658 - Response Time White -> Black: 12 ms - Overscan: 5% x 7% Detailed Timing Descriptors: DTD 2: 3840x2160 59.996625 Hz 16:9 133.312 kHz 533.250000 MHz (960 mm x 652 mm) Hfront 48 Hsync 32 Hback 80 Hpol P Vfront 3 Vsync 5 Vback 54 Vpol P -Checksum: 0x78 Unused space in Extension Block: 48 bytes +Checksum: 0x78 ---------------- -Warnings: - -Block 1, CTA-861 Extension Block: - Video Data Block: For improved preferred timing interoperability, set 'Native detailed modes' to 1. - Video Capability Data Block: S_PT is equal to S_IT and S_CE, so should be set to 0 instead. - -Failures: - -Block 1, CTA-861 Extension Block: - Detailed Timing Descriptor #2: Mismatch of image size 960x652 mm vs display size 960x540 mm. -EDID: - Base EDID: The DTD max image size is 960x652mm, which is larger than the display size 960.0x540.0mm. - -EDID conformity: FAIL +EDID conformity: PASS dxvk-0~git20230309.275e645/test/data/custom-uncommon-cta-vesa.edid000066400000000000000000000004001440230200600242000ustar00rootroot0000000000000014"`6xTL&PT/1YEY@@@0pZX2U< hdmi-4k-600 =Aa# ,4?<`CKlDM;B @< Ѐ0 52xdxvk-0~git20230309.275e645/test/data/custom-uncommon-cta-vesa.print000066400000000000000000000000751440230200600244370ustar00rootroot00000000000000make: The Linux Foundation model: hdmi-4k-600 serial: {null} dxvk-0~git20230309.275e645/test/data/dell-2408wfp-dp.edid000066400000000000000000000002001440230200600217630ustar00rootroot00000000000000+SM12/4 x"%Q0&PTK@qO(!:q8-@X,ED!q X,%Ď!NQ0@7!dxvk-0~git20230309.275e645/test/data/goldstar-ite6604-hdmi.print000066400000000000000000000000671440230200600234310ustar00rootroot00000000000000make: LG Electronics model: ITE6604 serial: 0x01010101 dxvk-0~git20230309.275e645/test/data/hp-5dq99aa-hdmi.diff000066400000000000000000000056311440230200600220530ustar00rootroot00000000000000--- ref +++ di @@ -24,7 +24,7 @@ DMT 0x10: 1024x768 60.003840 Hz 4:3 48.363 kHz 65.000000 MHz Standard Timings: DMT 0x52: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz - DMT 0x53: 1600x900 60.000000 Hz 16:9 60.000 kHz 108.000000 MHz (RB) + DMT 0x53: 1600x900 60.000000 Hz 16:9 60.000 kHz 108.000000 MHz DMT 0x55: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz DMT 0x45: 1920x1200 59.884600 Hz 16:10 74.556 kHz 193.250000 MHz DMT 0x3a: 1680x1050 59.954250 Hz 16:10 65.290 kHz 146.250000 MHz @@ -51,32 +51,21 @@ Supports YCbCr 4:2:2 Native detailed modes: 1 Video Data Block: - VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz - VIC 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz - VIC 3: 720x480 59.940060 Hz 16:9 31.469 kHz 27.000000 MHz - VIC 2: 720x480 59.940060 Hz 4:3 31.469 kHz 27.000000 MHz - VIC 31: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz - VIC 19: 1280x720 50.000000 Hz 16:9 37.500 kHz 74.250000 MHz - VIC 18: 720x576 50.000000 Hz 16:9 31.250 kHz 27.000000 MHz - VIC 17: 720x576 50.000000 Hz 4:3 31.250 kHz 27.000000 MHz - VIC 1: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz - Vendor-Specific Data Block (HDMI), OUI 00-0C-03: - Source physical address: 1.0.0.0 - DC_36bit - DC_30bit - DC_Y444 - Maximum TMDS clock: 310 MHz + VIC 16 + VIC 4 + VIC 3 + VIC 2 + VIC 31 + VIC 19 + VIC 18 + VIC 17 + VIC 1 Video Capability Data Block: YCbCr quantization: No Data RGB quantization: No Data PT scan behavior: Always Underscanned IT scan behavior: Always Underscanned CE scan behavior: Supports both over- and underscan - Vendor-Specific Data Block (AMD), OUI 00-00-1A: - Version: 1.1 - Minimum Refresh Rate: 46 Hz - Maximum Refresh Rate: 75 Hz - Flags 1.x: 0xed (MCCS) Colorimetry Data Block: BT2020cYCC BT2020YCC @@ -104,20 +93,12 @@ DTD 5: 1920x1080 74.972503 Hz 16:9 83.894 kHz 174.500000 MHz (597 mm x 339 mm) Hfront 48 Hsync 32 Hback 80 Hpol P Vfront 3 Vsync 5 Vback 31 Vpol N -Checksum: 0xa3 Unused space in Extension Block: 10 bytes +Checksum: 0xa3 ---------------- -Warnings: - -Block 1, CTA-861 Extension Block: - Video Capability Data Block: Set Selectable YCbCr Quantization to avoid interop issues. - Colorimetry Data Block: Set the sRGB colorimetry bit to avoid interop issues. - Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0. - Failures: Block 1, CTA-861 Extension Block: Video Capability Data Block: Set Selectable RGB Quantization to avoid interop issues. - EDID conformity: FAIL dxvk-0~git20230309.275e645/test/data/hp-5dq99aa-hdmi.edid000066400000000000000000000004001440230200600220350ustar00rootroot00000000000000"6 <"x*cESJ& PT@V^)P0 5US!.Kp HP 27 QD CN49120J6N  -Ig 8>+h.KsZ:q8-@X,EUS!:r8-@,EUS!v4P0 5US!*Dp8'@0 5US!dxvk-0~git20230309.275e645/test/data/hp-5dq99aa-hdmi.print000066400000000000000000000000611440230200600222670ustar00rootroot00000000000000make: HP Inc. model: HP 27 QD serial: CN49120J6N dxvk-0~git20230309.275e645/test/data/msi-mag321curv-dp.diff000066400000000000000000000112471440230200600224330ustar00rootroot00000000000000--- ref +++ di @@ -73,57 +73,32 @@ Supports YCbCr 4:2:2 Native detailed modes: 1 Video Data Block: - VIC 1: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz - VIC 2: 720x480 59.940060 Hz 4:3 31.469 kHz 27.000000 MHz - VIC 3: 720x480 59.940060 Hz 16:9 31.469 kHz 27.000000 MHz - VIC 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz - VIC 5: 1920x1080i 60.000000 Hz 16:9 33.750 kHz 74.250000 MHz - VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz - VIC 17: 720x576 50.000000 Hz 4:3 31.250 kHz 27.000000 MHz - VIC 18: 720x576 50.000000 Hz 16:9 31.250 kHz 27.000000 MHz - VIC 19: 1280x720 50.000000 Hz 16:9 37.500 kHz 74.250000 MHz - VIC 20: 1920x1080i 50.000000 Hz 16:9 28.125 kHz 74.250000 MHz - VIC 31: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz - VIC 32: 1920x1080 24.000000 Hz 16:9 27.000 kHz 74.250000 MHz - VIC 33: 1920x1080 25.000000 Hz 16:9 28.125 kHz 74.250000 MHz - VIC 34: 1920x1080 30.000000 Hz 16:9 33.750 kHz 74.250000 MHz - VIC 95: 3840x2160 30.000000 Hz 16:9 67.500 kHz 297.000000 MHz - VIC 97: 3840x2160 60.000000 Hz 16:9 135.000 kHz 594.000000 MHz - VIC 96: 3840x2160 50.000000 Hz 16:9 112.500 kHz 594.000000 MHz + VIC 1 + VIC 2 + VIC 3 + VIC 4 + VIC 5 + VIC 16 + VIC 17 + VIC 18 + VIC 19 + VIC 20 + VIC 31 + VIC 32 + VIC 33 + VIC 34 + VIC 95 + VIC 97 + VIC 96 Audio Data Block: - Linear PCM: - Max channels: 2 - Supported sample rates (kHz): 96 48 44.1 32 - Supported sample sizes (bits): 24 20 16 Speaker Allocation Data Block: - FL/FR - Front Left/Right - Vendor-Specific Data Block (HDMI), OUI 00-0C-03: - Source physical address: 1.0.0.0 - DC_36bit - DC_30bit - DC_Y444 - Maximum TMDS clock: 300 MHz - Extended HDMI video details: - HDMI VICs: - HDMI VIC 1: 3840x2160 30.000000 Hz 16:9 67.500 kHz 297.000000 MHz - HDMI VIC 2: 3840x2160 25.000000 Hz 16:9 56.250 kHz 297.000000 MHz - HDMI VIC 3: 3840x2160 24.000000 Hz 16:9 54.000 kHz 297.000000 MHz - Vendor-Specific Data Block (HDMI Forum), OUI C4-5D-D8: - Version: 1 - Maximum TMDS Character Rate: 600 MHz - SCDC Present - Supports 12-bits/component Deep Color 4:2:0 Pixel Encoding - Supports 10-bits/component Deep Color 4:2:0 Pixel Encoding Colorimetry Data Block: xvYCC601 xvYCC709 BT2020cYCC BT2020YCC BT2020RGB - Reserved MD0 YCbCr 4:2:0 Capability Map Data Block: - VIC 97: 3840x2160 60.000000 Hz 16:9 135.000 kHz 594.000000 MHz - VIC 96: 3840x2160 50.000000 Hz 16:9 112.500 kHz 594.000000 MHz HDR Static Metadata Data Block: Electro optical transfer functions: Traditional gamma - SDR luminance range @@ -133,7 +108,6 @@ Static metadata type 1 Desired content max luminance: 92 (366.802 cd/m^2) Desired content max frame-average luminance: 92 (366.802 cd/m^2) - Desired content min luminance: 0 (0.000 cd/m^2) Detailed Timing Descriptors: DTD 2: 2560x1440 59.950550 Hz 16:9 88.787 kHz 241.500000 MHz (700 mm x 390 mm) Hfront 48 Hsync 32 Hback 80 Hpol P @@ -144,29 +118,12 @@ DTD 4: 1280x768 59.870228 Hz 5:3 47.776 kHz 79.500000 MHz (700 mm x 390 mm) Hfront 64 Hsync 128 Hback 192 Hpol N Vfront 3 Vsync 7 Vback 20 Vpol P -Checksum: 0x4a Unused space in Extension Block: 5 bytes +Checksum: 0x4a ---------------- -Warnings: - -Block 0, Base EDID: - Display Range Limits: GTF support is deprecated in EDID 1.4. -Block 1, CTA-861 Extension Block: - Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0. -EDID: - Base EDID: Some timings are out of range of the Monitor Ranges: - Vertical Freq: 24.000 - 75.062 Hz (Monitor: 40.000 - 60.000 Hz) - Horizontal Freq: 27.000 - 135.000 kHz (Monitor: 135.000 - 135.000 kHz) - Failures: -Block 0, Base EDID: - Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match. Block 1, CTA-861 Extension Block: - Vendor-Specific Data Block (HDMI), OUI 00-0C-03: The HDMI Specification requires EDID 1.3 instead of 1.4. Colorimetry Data Block: Reserved bits MD0-MD3 must be 0. - HDMI VIC Codes must have their CTA-861 VIC equivalents in the VSB. - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. - EDID conformity: FAIL dxvk-0~git20230309.275e645/test/data/msi-mag321curv-dp.edid000066400000000000000000000004001440230200600224150ustar00rootroot000000000000006i=$F'xťVP&PTqO@Mp>0 5!(<< MAG321CURV DA2A019360041DQ !"_a`# m 8< `g]x\\V^)P0 5!f!VQ0F3!Q0@7!Jdxvk-0~git20230309.275e645/test/data/msi-mag321curv-dp.print000066400000000000000000000000701440230200600226470ustar00rootroot00000000000000make: Microstep model: MAG321CURV serial: DA2A019360041 dxvk-0~git20230309.275e645/test/data/panasonic-mei96a2-dp.diff000066400000000000000000000002231440230200600230700ustar00rootroot00000000000000--- ref +++ di @@ -33,9 +33,4 @@ ---------------- -Warnings: - -Block 0, Base EDID: - Missing Display Product Name. - EDID conformity: PASS dxvk-0~git20230309.275e645/test/data/panasonic-mei96a2-dp.edid000066400000000000000000000002001440230200600230600ustar00rootroot000000000000004xkeQK'PTd]PX 5dQX 5.>Y^ VVX14T058J10 dxvk-0~git20230309.275e645/test/data/panasonic-mei96a2-dp.print000066400000000000000000000000761440230200600233220ustar00rootroot00000000000000make: Panasonic Industry Company model: 0x96A2 serial: {null} dxvk-0~git20230309.275e645/test/data/samsung-s27a950d-dp.diff000066400000000000000000000026111440230200600225770ustar00rootroot00000000000000--- ref +++ di @@ -27,8 +27,6 @@ DTD 2: 1920x1080 99.930409 Hz 16:9 113.221 kHz 235.500000 MHz (field sequential R/L, 598 mm x 336 mm) Hfront 48 Hsync 32 Hback 80 Hpol P Vfront 3 Vsync 5 Vback 45 Vpol N - Display Range Limits: - Monitor ranges (GTF): 24-120 Hz V, 26-140 kHz H, max dotclock 300 MHz Display Product Name: 'S27A950D' Extension blocks: 1 Checksum: 0x1b @@ -41,29 +39,13 @@ Basic audio support Native detailed modes: 0 Audio Data Block: - Linear PCM: - Max channels: 2 - Supported sample rates (kHz): 48 44.1 32 - Supported sample sizes (bits): 24 20 16 Speaker Allocation Data Block: - FL/FR - Front Left/Right -Checksum: 0x71 Unused space in Extension Block: 115 bytes +Checksum: 0x71 ---------------- -Warnings: - -Block 0, Base EDID: - Display Range Limits: GTF support is deprecated in EDID 1.4. -Block 1, CTA-861 Extension Block: - Add a Colorimetry Data Block with the sRGB colorimetry bit set to avoid interop issues. - Failures: Block 0, Base EDID: Display Range Limits: GTF can't be combined with non-continuous frequencies. -Block 1, CTA-861 Extension Block: - Required 640x480p60 timings are missing in the established timings and the SVD list (VIC 1). - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. - EDID conformity: FAIL dxvk-0~git20230309.275e645/test/data/samsung-s27a950d-dp.edid000066400000000000000000000004001440230200600225660ustar00rootroot00000000000000L-<"x"`AVJ%PTop8@@0 5VP!^[p85@0 5VP!Zx S27A950D  # qdxvk-0~git20230309.275e645/test/data/samsung-s27a950d-dp.print000066400000000000000000000000761440230200600230260ustar00rootroot00000000000000make: Samsung Electric Company model: S27A950D serial: {null} dxvk-0~git20230309.275e645/test/data/sun-gh19ps-dvi.diff000066400000000000000000000010351440230200600220420ustar00rootroot00000000000000--- ref +++ di @@ -50,15 +50,4 @@ ---------------- -Warnings: - -Block 0, Base EDID: - Standard Timings: Standard Timing 1152x921 has a dubious odd vertical resolution. - Detailed Timing Descriptor #1: DTD is similar but not identical to DMT 0x23. -EDID: - Base EDID: Some timings are out of range of the Monitor Ranges: - Vertical Freq: 56.250 - 76.000 Hz (Monitor: 56.000 - 75.000 Hz) - Maximum Clock: 141.822 MHz (Monitor: 140.000 MHz) - Could be due to a Monitor Range off-by-one rounding issue - EDID conformity: PASS dxvk-0~git20230309.275e645/test/data/sun-gh19ps-dvi.edid000066400000000000000000000002001440230200600220300ustar00rootroot00000000000000NMR &xTL&PTq0*Q*@0p|,8KQ GH19PS 0432MR0406 !dxvk-0~git20230309.275e645/test/data/sun-gh19ps-dvi.print000066400000000000000000000001031440230200600222610ustar00rootroot00000000000000make: Sun Electronics Corporation model: GH19PS serial: 0432MR0406 dxvk-0~git20230309.275e645/test/data/viewsonic-vp2768-dp.diff000066400000000000000000000112121440230200600227230ustar00rootroot00000000000000--- ref +++ di @@ -38,11 +38,11 @@ DMT 0x24: 1280x1024 75.024675 Hz 5:4 79.976 kHz 135.000000 MHz Apple : 1152x870 75.061550 Hz 192:145 68.681 kHz 100.000000 MHz Standard Timings: - DMT 0x54: 2048x1152 60.000000 Hz 16:9 72.000 kHz 162.000000 MHz (RB) + DMT 0x54: 2048x1152 60.000000 Hz 16:9 72.000 kHz 162.000000 MHz DMT 0x52: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz DMT 0x3a: 1680x1050 59.954250 Hz 16:10 65.290 kHz 146.250000 MHz DMT 0x33: 1600x1200 60.000000 Hz 4:3 75.000 kHz 162.000000 MHz - DMT 0x53: 1600x900 60.000000 Hz 16:9 60.000 kHz 108.000000 MHz (RB) + DMT 0x53: 1600x900 60.000000 Hz 16:9 60.000 kHz 108.000000 MHz DMT 0x23: 1280x1024 60.019740 Hz 5:4 63.981 kHz 108.000000 MHz DMT 0x1c: 1280x800 59.810326 Hz 16:10 49.702 kHz 83.500000 MHz DMT 0x55: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz @@ -79,35 +79,29 @@ Supports YCbCr 4:2:2 Native detailed modes: 1 Video Data Block: - VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (native) - VIC 5: 1920x1080i 60.000000 Hz 16:9 33.750 kHz 74.250000 MHz - VIC 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz - VIC 3: 720x480 59.940060 Hz 16:9 31.469 kHz 27.000000 MHz - VIC 2: 720x480 59.940060 Hz 4:3 31.469 kHz 27.000000 MHz - VIC 15: 1440x480 59.940060 Hz 16:9 31.469 kHz 54.000000 MHz - VIC 18: 720x576 50.000000 Hz 16:9 31.250 kHz 27.000000 MHz - VIC 19: 1280x720 50.000000 Hz 16:9 37.500 kHz 74.250000 MHz - VIC 30: 1440x576 50.000000 Hz 16:9 31.250 kHz 54.000000 MHz - VIC 31: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz - VIC 32: 1920x1080 24.000000 Hz 16:9 27.000 kHz 74.250000 MHz - VIC 33: 1920x1080 25.000000 Hz 16:9 28.125 kHz 74.250000 MHz - VIC 34: 1920x1080 30.000000 Hz 16:9 33.750 kHz 74.250000 MHz - VIC 1: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + VIC 16 (native) + VIC 5 + VIC 4 + VIC 3 + VIC 2 + VIC 15 + VIC 18 + VIC 19 + VIC 30 + VIC 31 + VIC 32 + VIC 33 + VIC 34 + VIC 1 Audio Data Block: - Linear PCM: - Max channels: 2 - Supported sample rates (kHz): 192 176.4 96 88.2 48 44.1 32 - Supported sample sizes (bits): 24 20 16 Speaker Allocation Data Block: - FL/FR - Front Left/Right Detailed Timing Descriptors: DTD 2: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (597 mm x 336 mm) Hfront 88 Hsync 44 Hback 148 Hpol P Vfront 4 Vsync 5 Vback 36 Vpol P - DTD 3: 1920x1080i 60.000000 Hz 16:9 33.750 kHz 74.250000 MHz (597 mm x 336 mm) + DTD 3: 1920x540 i 60.053381 Hz 32:9 33.750 kHz 74.250000 MHz (597 mm x 336 mm) Hfront 88 Hsync 44 Hback 148 Hpol P - Vfront 2 Vsync 5 Vback 15 Vpol P Vfront +0.5 Odd Field - Vfront 2 Vsync 5 Vback 15 Vpol P Vback +0.5 Even Field + Vfront 2 Vsync 5 Vback 15 Vpol P DTD 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz (597 mm x 336 mm) Hfront 110 Hsync 40 Hback 220 Hpol P Vfront 5 Vsync 5 Vback 20 Vpol P @@ -117,28 +111,14 @@ DTD 6: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz (597 mm x 336 mm) Hfront 528 Hsync 44 Hback 148 Hpol P Vfront 4 Vsync 5 Vback 36 Vpol P -Checksum: 0xa6 Unused space in Extension Block: 10 bytes +Checksum: 0xa6 ---------------- -Warnings: - -Block 1, CTA-861 Extension Block: - Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0. -EDID: - Base EDID: Some timings are out of range of the Monitor Ranges: - Vertical Freq: 24.000 - 75.062 Hz (Monitor: 50.000 - 75.000 Hz) - Failures: Block 0, Base EDID: - Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match. Display Range Limits: Reserved bits of byte 14 are non-zero. Display Range Limits: Reserved bits of byte 15 are non-zero. Display Range Limits: Reserved bits of byte 16 are non-zero. -Block 1, CTA-861 Extension Block: - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. -EDID: - CTA-861: Native progressive timings are a mix of several resolutions. - EDID conformity: FAIL dxvk-0~git20230309.275e645/test/data/viewsonic-vp2768-dp.edid000066400000000000000000000004001440230200600227150ustar00rootroot00000000000000Zc4 <"x?feTL&PT@V^)P0 5UP!UY5171500307 2KZ ;<VP2768 SeriesN !"# :q8-@X,EUP!q X,%UP!rQ n(UUP! Њ ->UP!:r8-@,EUP!dxvk-0~git20230309.275e645/test/data/viewsonic-vp2768-dp.print000066400000000000000000000001061440230200600231470ustar00rootroot00000000000000make: ViewSonic Corporation model: VP2768 Series serial: UY5171500307 dxvk-0~git20230309.275e645/test/di-edid-print.c000066400000000000000000000022211440230200600203740ustar00rootroot00000000000000#include #include #include #include static const char * str_or_null(const char *str) { return str ? str : "{null}"; } static void print_info(const struct di_info *info) { char *str; str = di_info_get_make(info); printf("make: %s\n", str_or_null(str)); free(str); str = di_info_get_model(info); printf("model: %s\n", str_or_null(str)); free(str); str = di_info_get_serial(info); printf("serial: %s\n", str_or_null(str)); free(str); } int main(int argc, char *argv[]) { FILE *in; static uint8_t raw[32 * 1024]; size_t size = 0; struct di_info *info; in = stdin; if (argc > 1) { in = fopen(argv[1], "r"); if (!in) { perror("failed to open input file"); return 1; } } while (!feof(in)) { size += fread(&raw[size], 1, sizeof(raw) - size, in); if (ferror(in)) { perror("fread failed"); return 1; } else if (size >= sizeof(raw)) { fprintf(stderr, "input too large\n"); return 1; } } fclose(in); info = di_info_parse_edid(raw, size); if (!info) { perror("di_edid_parse failed"); return 1; } print_info(info); di_info_destroy(info); return 0; } dxvk-0~git20230309.275e645/test/edid-decode-check.sh000077500000000000000000000005671440230200600213520ustar00rootroot00000000000000#!/bin/sh -eu workdir="$(mktemp -d)" cleanup() { rm -rf "$workdir" } trap cleanup EXIT edid="$1" diff="${edid%.edid}.diff" "$REF_EDID_DECODE" --skip-hex-dump --check --skip-sha <"$edid" >"$workdir/ref" || [ $? = 254 ] "$DI_EDID_DECODE" <"$edid" >"$workdir/di" || [ $? = 254 ] if [ -f "$diff" ]; then patch "$workdir/ref" "$diff" fi diff -u "$workdir/ref" "$workdir/di" dxvk-0~git20230309.275e645/test/edid-decode-diff.sh000077500000000000000000000013011440230200600211700ustar00rootroot00000000000000#!/bin/sh -eu REF_EDID_DECODE="${REF_EDID_DECODE:-edid-decode}" BUILDDIR="${BUILDDIR:-./build}" DI_EDID_DECODE="${DI_EDID_DECODE:-${BUILDDIR}/di-edid-decode}" DI_EDID_PRINT="${DI_EDID_PRINT:-${BUILDDIR}/test/di-edid-print}" workdir="$(mktemp -d)" cleanup() { rm -rf "$workdir" } trap cleanup EXIT for edid in "$@"; do diff="${edid%.edid}.diff" "$REF_EDID_DECODE" --skip-hex-dump --check --skip-sha <"$edid" >"$workdir/ref" || [ $? = 254 ] "$DI_EDID_DECODE" <"$edid" >"$workdir/di" || [ $? = 254 ] if ! diff -u --label ref "$workdir/ref" --label di "$workdir/di" >"$workdir/diff"; then cp "$workdir/diff" "$diff" else rm -f "$diff" fi "$DI_EDID_PRINT" <"$edid" >"${edid%.edid}.print" done dxvk-0~git20230309.275e645/test/edid-print-check.sh000077500000000000000000000003211440230200600212470ustar00rootroot00000000000000#!/bin/sh -eu workdir="$(mktemp -d)" cleanup() { rm -rf "$workdir" } trap cleanup EXIT edid="$1" ref="${edid%.edid}.print" "$DI_EDID_PRINT" <"$edid" >"$workdir/printout" diff -u "$ref" "$workdir/printout" dxvk-0~git20230309.275e645/test/meson.build000066400000000000000000000021741440230200600177500ustar00rootroot00000000000000di_edid_print = executable( 'di-edid-print', 'di-edid-print.c', dependencies: di_dep, install: false, ) subdir_done() ref_edid_decode = find_program('edid-decode', native: true, required: false) if not ref_edid_decode.found() test('edid-decode-not-found', find_program('false')) subdir_done() endif test_harness = find_program('./edid-decode-check.sh', native: true) print_harness = find_program('./edid-print-check.sh', native: true) test_cases = [ 'acer-p1276', 'apple-xdr-dp', 'custom-uncommon-cta-vesa', 'dell-2408wfp-dp', 'goldstar-ite6604-hdmi', 'hp-5dq99aa-hdmi', 'msi-mag321curv-dp', 'panasonic-mei96a2-dp', 'samsung-s27a950d-dp', 'sun-gh19ps-dvi', 'viewsonic-vp2768-dp', ] foreach tc : test_cases test( 'decode-' + tc, test_harness, args: [files('data/' + tc + '.edid')], env: [ 'REF_EDID_DECODE=' + ref_edid_decode.full_path(), 'DI_EDID_DECODE=' + di_edid_decode.full_path(), ], depends: [di_edid_decode], ) test( 'print-' + tc, print_harness, args: [files('data/' + tc + '.edid')], env: [ 'DI_EDID_PRINT=' + di_edid_print.full_path(), ], depends: [di_edid_print], ) endforeach dxvk-0~git20230309.275e645/tool/000077500000000000000000000000001440230200600156005ustar00rootroot00000000000000dxvk-0~git20230309.275e645/tool/gen-dmt.py000077500000000000000000000111721440230200600175120ustar00rootroot00000000000000#!/usr/bin/env python3 import os import subprocess import sys def parse_hex_byte(s): assert(s.endswith("h")) s = s[:-1] assert(0 <= int(s, 16) <= 255) return "0x" + s def parse_hex_list(s): if s == "n/a": return None if s.startswith("("): assert(s.endswith(")h")) s = s[1:-2] l = [b.strip() for b in s.split(",")] l = [b[:-1] if b.endswith("h") else b for b in l] for b in l: assert(0 <= int(b, 16) <= 255) return "0x" + "".join(l) def parse_pixel_param(l): l = l[2].split(" ") assert(len(l) >= 2 and l[1] == "Pixels") return int(l[0]) def parse_line_param(l): l = l[1].split(" ") assert(len(l) >= 2 and l[1] == "lines") return int(l[0]) def parse_timing(page): lines = [l.strip() for l in page.splitlines()] if len(lines) < 6: return None try: i = lines.index("Detailed Timing Parameters") except ValueError: return None raw_metadata = lines[1:i] raw_params = lines[i+1:] metadata = {} for l in raw_metadata: if not ": " in l: continue k, v = l.split(":", 1) metadata[k.strip()] = v.strip() assert("Resolution" in metadata and "EDID ID" in metadata) if "Proposed" in metadata and not "Adopted" in metadata: print("skipping proposed but not adopted timing: " + metadata["Resolution"], file=sys.stderr) return None params = {} for l in raw_params: if not " = " in l: continue tokens = [l.strip() for l in l.split("=")] params[tokens[0]] = tokens[1:] assert("Timing Name" in params) res = metadata["Resolution"] size, rest = res.split(" at ", 1) horiz_video, vert_video = size.split("x", 1) refresh_rate_hz, rest = rest.split(" Hz ", 1) horiz_video = int(horiz_video.strip()) vert_video = int(vert_video.strip()) refresh_rate_hz = float(refresh_rate_hz.strip()) ids = {} for kv in metadata["EDID ID"].split(";"): k, v = kv.split(":") ids[k.strip()] = v.strip() assert("DMT ID" in ids) dmt_id = parse_hex_byte(ids["DMT ID"]) edid_std_id = parse_hex_list(ids["Std. 2 Byte Code"]) cvt_id = parse_hex_list(ids["CVT 3 Byte Code"]) pixel_clock_mhz = float(params["Pixel Clock"][0].split(";")[0]) horiz_blank = parse_pixel_param(params["Hor Blank Time"]) horiz_front_porch = parse_pixel_param(params["// H Front Porch"]) horiz_sync_pulse = parse_pixel_param(params["Hor Sync Time"]) horiz_border = parse_pixel_param(params["// H Right Border"]) assert(horiz_border == parse_pixel_param(params["// H Left Border"])) vert_blank = parse_line_param(params["Ver Blank Time"]) vert_front_porch = parse_line_param(params["// V Front Porch"]) vert_sync_pulse = parse_line_param(params["Ver Sync Time"]) vert_border = parse_line_param(params["// V Bottom Border"]) assert(vert_border == parse_line_param(params["// V Top Border"])) return { "dmt_id": dmt_id, "edid_std_id": 0 if edid_std_id is None else edid_std_id, "cvt_id": 0 if cvt_id is None else cvt_id, "horiz_video": horiz_video, "vert_video": vert_video, "refresh_rate_hz": refresh_rate_hz, "pixel_clock_hz": int(pixel_clock_mhz * 1000 * 1000), "horiz_blank": horiz_blank, "horiz_front_porch": horiz_front_porch, "horiz_sync_pulse": horiz_sync_pulse, "horiz_border": horiz_border, "vert_blank": vert_blank, "vert_front_porch": vert_front_porch, "vert_sync_pulse": vert_sync_pulse, "vert_border": vert_border, } if len(sys.argv) != 2: print("usage: gen-dmt.py ", file=sys.stderr) sys.exit(1) in_path = sys.argv[1] in_basename = os.path.basename(in_path) tool_dir = os.path.dirname(os.path.realpath(__file__)) out_path = tool_dir + "/../dmt-table.c" cmd = ["pdftotext", "-nodiag", "-layout", in_path, "-"] page = "" timings = [] for l in subprocess.check_output(cmd, text=True): if l.startswith("\f"): t = parse_timing(page) if t is not None: timings.append(t) page = l[1:] else: page += l with open(out_path, "w+") as f: f.write("/* DO NOT EDIT! This file has been generated by gen-dmt.py from {}. */\n\n".format(in_basename)) f.write('#include "dmt.h"\n\n') f.write("const struct di_dmt_timing _di_dmt_timings[] = {\n") for t in timings: f.write("\t{\n") for k, v in t.items(): f.write("\t\t.{} = {},\n".format(k, v)) f.write("\t},\n") f.write("};\n\n") f.write("const size_t _di_dmt_timings_len = {};\n".format(len(timings))) dxvk-0~git20230309.275e645/tool/gen-search-table.py000077500000000000000000000046011440230200600212570ustar00rootroot00000000000000#!/usr/bin/env python3 """ string to string mapping table License: MIT Copyright (c) 2020 Simon Ser Copyright 2022 Collabora, Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import sys def escape_for_c(s): l = [c if c.isalnum() or c in ' .,' else '\\%03o' % ord(c) for c in s] return ''.join(l) if len(sys.argv) != 4: print('usage: ' + sys.argv[0] + ' ', file=sys.stderr) sys.exit(1) infile = sys.argv[1] outfile = sys.argv[2] ident = sys.argv[3] records = {} with open(infile, mode='r', encoding='utf-8') as f: for line in f: [pnpid, name] = line.split(maxsplit=1) if len(pnpid) != 3: print("Warning: skipping invalid PNP ID %s" % (repr(pnpid)), file=sys.stderr) continue records[pnpid] = escape_for_c(name.strip()) with open(outfile, mode='w', encoding='utf-8') as f: f.write( f''' #include #include const char * {ident}(const char *key); const char * {ident}(const char *key) {{ size_t len = strlen(key); size_t i; uint32_t u = 0; if (len > 4) return NULL; for (i = 0; i < len; i++) u = (u << 8) | (uint8_t)key[i]; switch (u) {{ ''') for id in sorted(records.keys()): u = 0 for c in id: u = (u << 8) | ord(c) f.write(f' case {u}: return "{records[id]}";\n') f.write( f''' default: return NULL; }} }} ''')