> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QIR SDK (Linux) Blog

Technical deep dives into QIR SDK sample pipelines, plus release highlights for every new SDK version.

export const POSTS = {
  apriltag: {
    href: "./blogs/apriltag-pipeline-under-the-hood",
    category: "Deep dives",
    title: "Under the hood: the AprilTag pipeline",
    description: "How five ROS 2 nodes turn a raw camera feed into millimeter-accurate tag poses.",
    date: "July 2026"
  },
  "face-detection": {
    href: "./blogs/face-detection-under-the-hood",
    category: "Deep dives",
    title: "Under the hood: two-stage face detection with sample_face_detection",
    description: "How one inference node runs a face detector and a landmark model back to back, entirely on-device.",
    date: "August 2026"
  },
  "release-2-8-0": {
    href: "./blogs/qir-sdk-2-8-0-whats-new",
    category: "Releases",
    title: "QIR SDK 2.8.0: what's new",
    description: "Qualcomm Linux overlays come to the QIR SDK, nine more samples run on the IQ-8275 EVK, and the eSDK goes from build to flash to your own recipes.",
    date: "September 2026"
  }
};

export const PostCard = ({postKey, hidden, children}) => {
  const post = POSTS[postKey];
  return <a href={post.href} className="mint-group not-prose" style={{
    textDecoration: "none",
    color: "inherit",
    display: hidden ? "none" : "flex",
    flexDirection: "column"
  }}>
      <div style={{
    position: "relative",
    aspectRatio: "16 / 9",
    overflow: "hidden",
    borderRadius: "8px"
  }}>
        {children}
      </div>
      <div style={{
    paddingTop: "0.85rem"
  }}>
        <div style={{
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    marginBottom: "0.5rem"
  }}>
          <span style={{
    fontSize: "0.7rem",
    fontWeight: 600,
    padding: "0.15rem 0.55rem",
    borderRadius: "4px",
    background: "rgba(128,128,128,0.12)",
    color: "inherit"
  }}>{post.category}</span>
          <span style={{
    fontSize: "0.8rem",
    color: "rgba(128,128,128,0.9)"
  }}>{post.date}</span>
        </div>
        <div className="group-hover:mint-text-[#31017D] mint-transition-colors mint-duration-200" style={{
    fontSize: "1rem",
    fontWeight: 600,
    lineHeight: 1.4,
    marginBottom: "0.35rem"
  }}>{post.title}</div>
        <p style={{
    fontSize: "0.85rem",
    color: "rgba(128,128,128,0.9)",
    lineHeight: 1.55,
    margin: 0,
    display: "-webkit-box",
    WebkitLineClamp: 2,
    WebkitBoxOrient: "vertical",
    overflow: "hidden"
  }}>
          {post.description}
        </p>
      </div>
    </a>;
};

export const findPostCard = (el, depth = 0) => {
  if (!el || !el.props || depth > 5) return null;
  if (el.props.postKey) return el;
  return React.isValidElement(el.props.children) ? findPostCard(el.props.children, depth + 1) : null;
};

export const matchesPost = (post, query, category) => {
  if (!post) return false;
  if (category && post.category !== category) return false;
  const q = query.trim().toLowerCase();
  if (!q) return true;
  return post.title.toLowerCase().includes(q) || post.description.toLowerCase().includes(q) || post.category.toLowerCase().includes(q);
};

export const cloneWithHidden = (el, hidden) => {
  if (el.props.postKey) return React.cloneElement(el, {
    hidden
  });
  return React.cloneElement(el, {
    children: cloneWithHidden(el.props.children, hidden)
  });
};

export const FilterGrid = ({query, category, children}) => {
  const items = React.Children.toArray(children);
  const posts = items.map(child => {
    const card = findPostCard(child);
    return card ? POSTS[card.props.postKey] : undefined;
  });
  const anyVisible = posts.some(post => matchesPost(post, query, category));
  return <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: "2rem 1.5rem"
  }}>
      {items.map((child, i) => cloneWithHidden(child, !matchesPost(posts[i], query, category)))}
      {!anyVisible && <p style={{
    fontSize: "0.85rem",
    color: "rgba(128,128,128,0.9)",
    gridColumn: "1 / -1"
  }}>
          No articles found.
        </p>}
    </div>;
};

export const CATEGORIES = [{
  key: null,
  label: "All articles"
}, {
  key: "Deep dives",
  label: "Deep dives"
}, {
  key: "Releases",
  label: "Releases"
}];

export const BlogSearch = ({children}) => {
  const [query, setQuery] = React.useState("");
  const [category, setCategory] = React.useState(null);
  return <div>
      <div style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    flexWrap: "wrap",
    gap: "0.75rem",
    marginBottom: "1.5rem"
  }}>
        <div style={{
    display: "flex",
    gap: "0.5rem"
  }}>
          {CATEGORIES.map(c => <button key={c.label} onClick={() => setCategory(c.key)} className="not-prose" style={{
    fontSize: "0.85rem",
    fontWeight: 600,
    padding: "0.4rem 0.9rem",
    borderRadius: "999px",
    border: category === c.key ? "1px solid #31017D" : "1px solid rgba(128,128,128,0.3)",
    background: category === c.key ? "#31017D" : "transparent",
    color: category === c.key ? "#fff" : "inherit",
    cursor: "pointer"
  }}>
              {c.label}
            </button>)}
        </div>
        <div style={{
    display: "flex",
    alignItems: "center",
    gap: "0.4rem",
    padding: "0.3rem 0.75rem",
    borderRadius: "999px",
    border: "1px solid rgba(128,128,128,0.3)",
    background: "rgba(128,128,128,0.06)"
  }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{
    flexShrink: 0,
    opacity: 0.6
  }}>
            <circle cx="11" cy="11" r="8"></circle>
            <path d="m21 21-4.3-4.3"></path>
          </svg>
          <input type="text" value={query} onChange={e => setQuery(e.target.value)} placeholder="Search articles..." style={{
    border: "none",
    outline: "none",
    background: "transparent",
    color: "inherit",
    fontSize: "0.8rem",
    width: "130px"
  }} />
        </div>
      </div>
      <FilterGrid query={query} category={category}>
        {children}
      </FilterGrid>
    </div>;
};

<BlogSearch>
  <PostCard postKey="apriltag">
    <img noZoom src="https://mintcdn.com/qualcomm-prod/IP0o0G5fE3MFmCJ8/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample-apriltag.gif?s=e43ac13c8da6439792b27660b75d4652" alt="Under the hood: the AprilTag pipeline" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} width="720" height="456" data-path="SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample-apriltag.gif" />
  </PostCard>

  <PostCard postKey="face-detection">
    <img noZoom src="https://mintcdn.com/qualcomm-prod/IP0o0G5fE3MFmCJ8/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample_face_detection_result.gif?s=5575af3d322838daabe2be8efaa3ee3f" alt="Under the hood: two-stage face detection with sample_face_detection" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} width="768" height="432" data-path="SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample_face_detection_result.gif" />
  </PostCard>

  <PostCard postKey="release-2-8-0">
    <img noZoom src="https://mintcdn.com/qualcomm-prod/IP0o0G5fE3MFmCJ8/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/qrb-ros-camera_IQ-9075-EVK-main-board.png?fit=max&auto=format&n=IP0o0G5fE3MFmCJ8&q=85&s=12eff3df1a9b7938b7b4c53e98bb0cdc" alt="QIR SDK 2.8.0: what's new" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} width="1292" height="998" data-path="SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/qrb-ros-camera_IQ-9075-EVK-main-board.png" />
  </PostCard>
</BlogSearch>
