CppCast - GPU Programming and HLSL with Chris Bieneman

Episode Date: May 18, 2026

Jason and Mathieu are joined by Chris Bieneman to discuss GPU programming and the evolution of HLSL, the challenges of floating-point determinism on GPUs, and lessons from over a decade of shading lan...guage and compiler work. News Sure, xor'ing a register with itself is the idiom for zeroing it out, but why not sub? - Raymond Chen, The Old New Thing Preventing Integer Overflow in Physical Computations - Mateusz Pusz, mp-units Let's check vibe code that acts like optimized C++ but is actually a mess - Andrey Karpov, PVS-Studio Links Developer Toolchain for the PlayStation 4 - Paul Robinson (2013 LLVM US Dev Meeting) HLSL: Decades in the Making - Chris Bieneman (Khronos Shading Languages Symposium 2026) GLSL: Origins, Observations and Opportunities - Randi Rost (Khronos Shading Languages Symposium 2026) Redefining the Software Engineering Profession for AI - Mark Russinovich & Scott Hanselman (ACM) Two Compilers, One Language, No Specification - Chris Bieneman (2024 LLVM Developers' Meeting) Ecma TC57 - HLSL Standardization Committee (GitHub) microsoft/hlsl-specs - HLSL Specifications (GitHub)

Transcript
Discussion (0)
Starting point is 00:00:00 Welcome to the 407th episode of CBPcast, the first podcast for C++ developers by C++ developers. I'm your host, Jason Turner. Every fourth episode of C++ Weekly will be a crossover episode of CPPCast. You can choose to watch the podcast on YouTube or listen on your favorite service. I'm joined by my co-host, Matthew Ropere. How are you doing, Matthew? Great. What about you?
Starting point is 00:00:23 I know. I'm doing all right. Do you want to give our audience, like, a quick update as to what you have been up to lately? Oh, oh, well, I'm still consulting on my own for the foreseeable two weeks and something. And then I'm going to continue consulting, but for a company. I haven't announced it yet, but it's a pretty famous company. It will be known. It'll probably be public by the time this airs, which will be mid-May, I guess.
Starting point is 00:00:57 Okay, then yes. Then go to LinkedIn and check my profile if you are in the future and absolutely want. The amazing thing about recording stuff in the past is the time travel involved. All right, this week we are joined by Chris Vieneman. Chris is the technical lead for the HLSSL compiler at Microsoft and the chair of ECMA TC57, the newly formed Standards Committee for HLSL. He's on the LLVM Board of Directors. In general, his career focus is on open source compilers and more recently language development. How are you doing, Chris?
Starting point is 00:01:37 Doing great. Thanks for having me on here. This is super excited. Awesome. I am really glad that you agreed to come on as well. Yeah, I think this was a great recommendation by our previous host, a guest actually, right? Yes. So our last guest actually recommended that you come on.
Starting point is 00:01:54 Keith and I have been having a lot of fun back and forth because he's one of our users who stretches our programming language to breaking points and then, you know, gives talks about it at conferences, shaming us into fixing our language. So it's been a really fun dynamic. You know, I respect that because that has been my primary influence in the C++ community is pointing out flaws and letting other people fix them. I will say since you guys mentioned Keith, I do want to. point out one thing that came up in your episode with Keith is there's a certain game platform, not by my employer, and you guys had a lengthy discussion as to what compiler they use. And I can definitively tell you, because this is on the internet. In 2013 at the LVM US developer meeting, Paul Robinson gave a talk, developer tool chain for the PlayStation 4, and it is out there, it is actually well known
Starting point is 00:02:52 that Sony has adopted Klang. I can tell you that. We can stop pretending to secret. Yeah, since 2013, at least. See, I thought that that was well known, but I have signed enough NDAs with enough companies for, like, training and stuff that, like, sometimes I can't remember.
Starting point is 00:03:12 Like, did I learn this under an NDA? Did I learn this? You know, like... Yeah, I mean, I'm in the comfortable position that I haven't signed any NDAs with Sony. So I don't have to worry about it too much. But the YouTube video from Paul's talk is actually pretty good because they go through why they chose to align on Clang. And it's a really good, strongly recommend it.
Starting point is 00:03:36 You said that was 2014? 2013. 13. That's relatively early in the conference talks that are publicly available on the internet, I feel like. Yeah, I think LVM. went back and added a bunch of recordings going back to like i want to say like 2006 or something oh wow but 20 2011 or so is when they really started every conference just posting the videos afterwards okay that's cool yeah i know that some of the early um like going native talks was that
Starting point is 00:04:13 like 2014 15 or whatever like they all just disappeared because they were on Microsoft's channel 9 website? Yeah, yeah, I hate that now. It's just it's just dead links everywhere when you try to find the going native talks and whatnot.
Starting point is 00:04:29 I think some of them, luckily people have redone somewhere else. Like the famous Shunparent one, I think, was done on the native for a while, but you can find copies because you redoubt the same training at another place. But yeah, it's, I don't want to say
Starting point is 00:04:44 that's why people should scrape YouTube in every website that has videos. just, uh, it is crazy about stuff that disappears. But you're not going to tell people to scrape things, but you're going to, you know, torrent it all out there for us, right? Right. No comment, it seems. No comments.
Starting point is 00:05:01 Exactly. Uh, well, okay, now we're officially into the banter portion of the podcast, but, um, I did know someone at one time whose hobby, uh, back in the Netflix DVD era, his, his, his, his, hobby was trying to make a local backup of Netflix. So he would get DVDs, immediately rip them, send them back, and then get the next batch, right? Because as soon as they received the last ones, they would send you the next thing in your queue. And, like, Netflix never questioned that he was somehow watching like eight movies a day or whatever. Anyhow. All right. So we have some news items. And like I've said before, since we're not doing a weekly cadence, these are just
Starting point is 00:05:44 things that you may or may not have missed that came up in the last month. month. And the first one we have here is the article from Raymond Chen on sure, X-Oring a register with itself is the idiom for zeroing out, but why not sub? This was a fun article for me to read. Oh, I haven't, but I definitely should read it. I know the extra trick from like 20 years ago, and I know that at the time people say it's because it's, it was faster than, you know, like you could only do it in one instruction. I haven't read the article, so I haven't see why it's another.
Starting point is 00:06:21 I had to explain why it's better than move zero to some people, but I never thought about sub. Sub is the question that Raymond brings up here because it's the same number of bytes and theoretically also the same performance as XOR. It's kind of, it seems almost like an arms race. Like either one of them, sub EAX comma EAX or XOR XOR X, EX, whatever, will actually get handled during instruction decode time on Intel. but maybe hypothetically depending on which iteration of AMD are using, maybe the XOR is still faster than the sub version.
Starting point is 00:06:58 So it's like, it's just like, well, we all know that the XOR version is the faster. So we'll stick with that. But and then the comments are also interesting about the history of this with. It is, I think one of this thing that maybe makes you realize that the assembly lies, or at least like the assembly gives you the illusion of knowing what you're doing and what's happening. then the microcode completely like lies to you and does whatever it wants. I had a similar rabbit hole a couple years back actually because I was looking at MEMSET and which is faster, which version of MEMSET is faster because you know you can do some stuff
Starting point is 00:07:37 with AVX, you can try to do like the trick with the loop that that jumps out of the switch case for like rounding the three, four and three were one bites at the end. There's a lot of things. And then it turns out just Intel Optimize. is if you just do bite by byte in a loop. They just detect what you're doing. They figure out what the number is and they just do it on the back end for you.
Starting point is 00:07:56 And it literally doesn't matter on new CPUs. It might even be faster to just do a stupid, like set ECX to the number of bytes you want to zero and then do a rep move us. Right. I mean, this is the truth is you always have to measure these things, right? Like you can't just assume anything. I, reading this article reminded me of the old,
Starting point is 00:08:19 3xor swap thing. And like the first time I ever saw that in an actual code base, it was like swapping two pointers that were stored in memory. And they're like, oh, well, it's faster to use 3xors than to just, you know, have a temporary. And I'm like, no, it's not. It's just more confusing to read the code. Like, you know, getting people to actually like, I don't know,
Starting point is 00:08:43 process the mythologies that they're told and understand what reality is, is always an interesting challenge. Yeah, that's, what is I just recently saw someone re-quote Titus Winters, I believe. Oh, was this actually on, there's something I was looking up for this episode. So forgive me, Chris, if it was like, I don't know on your website or something. But it's a quote from Titus, it's something like, clever is an insult, not a compliment. So I don't know. I'm paraphrasing something along those lines.
Starting point is 00:09:17 I don't know that I'm familiar with that quote, but that definitely sounds like an ideology that I would agree with. Yeah. It took me a second here. I found it, but Charlie Bay gave a talk at C++ now a long time ago, 2016 or something like that. And it's along the lines of basically you literally have no idea what your CPU is doing. To go back to your point, Matthew.
Starting point is 00:09:39 Yeah, I like the one about being clever is actually an insult. Although as C++ developers, it can be risky, because then people start arguing the same thing when you start using template or constex per like, oh, I don't know what he's doing, do a full loop. That I understand. Yeah. I had students argue with me on using structured bindings
Starting point is 00:10:00 and arranged for, and I'm like, it's Python. It's Python. It's not clever. It's Python. It's 10 years too late. What was the next article here? We had Pemattush, Matousche has an article on preventing integer overflow in physical computations. Now, before we started recording, you had a mild comment about this, Chris. I mean, I work in GPUs, so we don't really care about safety or overflows or things. You know, it is what it is.
Starting point is 00:10:35 You probably do rely a lot on like the I-Triple-E rules, right? Like you don't have overflow, but you are going to have saturating, math, I think would be a fair way to put that. Is that fair? It depends. I mean, on some things we have saturating and other things we don't, we have, you know, HLSL is a weird language where like, we, we actually by default effectively have, you know, the LVM fast math rules applied to everything. Oh, which means you have no idea what the computation is going to be. Right. Like, it's, it's, and, and then actually, um, my least favorite language feature in HLSL is the, the precise keyword. which I could rant for a whole hour about how the precise keyword in HLSL, one is poorly named
Starting point is 00:11:19 because it actually makes your math generally less precise because it prevents any optimization that would change precision even if it would make the precision higher. So like fusion, which often makes precision higher because the intermediate roundings have more bits. It doesn't allow you to do any FP contraction if you use the precise keyword. Oh, ow. But worse than that, the precise keyword doesn't actually apply to the variable you put it on. It applies to all of the expressions that contribute to the value of the variable you put it on. It is intended to cross-function boundaries in this like really weird way that only works if you inline everything and let your compiler solve all of the problems for you.
Starting point is 00:12:01 It doesn't work. It's it's a giant mess of bugs. Is it like one of these like time travel U.B kind of things? I mean, like it literally has to trace backward through the program and say, oh, because you put precise here. Yes. And it and it, so, so HLSL and GLSL both have this language feature. It basically works the same way. And in both of them, it's basically unimplementable.
Starting point is 00:12:24 The only way that it works is if you assume that your entire program is only ever one translation unit, that you can inline everything at your IR level and that you can back propagate up the attribute all the way. It's insane. Huh. We're both making a face like, what? Well, first part of me is thinking, hey, I know C++ programmers who work that way. Literally everything's a template that's Constexper in a header file. What's a C++ file, right?
Starting point is 00:13:00 And you can get extreme benefits from this at runtime. And then I was pondering, I know that LVM has the ability to mark a value as like, poison. Yes. And that affects the computations afterward. And then I found myself wondering, like, what, is there some way that you could propagate up using a similar mechanism in LLVM? And I don't know what my brain is all over the place. Propagating up is just really hard, right? Yeah, yeah. It's like programming languages and compilers are by design like DAGs that propagate down. Like everything is really easy to propagate down. It's really hard to propagate back up. And, And if you have function calls and things in the middle, then like, you may have to clone a function
Starting point is 00:13:46 because in one context it's used with this property and another context it isn't. And that becomes combinatoric because it can depend on the number of arguments of the function. And so you may need to clone a function multiple times with different properties of different arguments in order to satisfy the constraint. It's gnarly. Wow. Yeah. We'll definitely have to come back to that.
Starting point is 00:14:13 I was going to say, is it a recent mistake, or is it more like, you know, like scenes of the farther thing that we did in the 90s or? Oh, this is, this is, I mean, not the 90s. I mean, nothing in HLSL goes back to the 90s, but it is definitely, you know, probably a 15-year-old language feature that, at least, if not older. The main point of the language feature, too, just for context, is that sometimes you have the need to compute, basically, from the same input, you need to compute the same value in multiple different shader programs, and then you need to be able to compare them. And as we all know, with floating point rounding, you're not necessarily going to get the same result. And so what people do is this precise keyword is your way of saying, okay, I need this math to be the same every time I can.
Starting point is 00:15:05 compute it. Given the same input, you have to compute it the same way. Floating point is a hard, hard problem. Yeah, I will refer. There's been several good talks recently at CLS Plus conferences. And at the moment, the name of the talks is escaping me, but anyone who wants to look this up, that is basically about how broken floating point computations are. Like, you can do the exact same things, thinking that you're following the exact same AAA I-E-E-RULE rules on exactly the same hardware, but two different compilers, two different operating systems, and get different results.
Starting point is 00:15:39 Guy did the thing about that, because it's a common issue of video games. So we would like to be using floating points for game logic, but then game logic has to be somewhat consistent across clients or else like, you know, the classic, oh, if they do math on the different clients differently than on one client, the player is dead from damage, and on the other one, you still has one health left. And then you get, you get wonky behaviors. So the solution that, for example, I worked with for years has been just ignore that float exists.
Starting point is 00:16:10 Literally the first thing you drill into new programmers is floats are for those weirders. We do graphics. We don't do floats here. We do fixed points. Everything is fixed point. You know all that. If I see a float in game code, you're going to get shot.
Starting point is 00:16:22 And that's the last time you will see a float. And I know Guy went the other way, he said, no, I will fault everybody at gunpoint to ease the exact same version of the same compiler on every platform. with the exact same compile flags. I mean, you can do that with Kling, right? Yeah. Unfortunately, Kling is kind of your only option to do that.
Starting point is 00:16:44 I think that's what he did back when he was at Creative Assembly. But the point he was making in the talk is that it's actually not a lot, and it's mostly whether or not you're allowed to fuse that is not completely decided. And he said if we could just have a model that actually makes it deterministic, we would be done. And I know that's the work he was on at the time. The challenge with fusing, though, that gets tricky, and this is where the precise keyword really comes in for HLSL is that the compiler might decide before doing fusion that, you know, and subexpression elimination or something refolds the other math around it. And so you may have literally what seems to the user as the same math in both places, but on one side, it gets fused because there's nothing else using the intermediate results or doing the same intermediate computation.
Starting point is 00:17:35 But in the other program, you may actually have something that is the exact same intermediate computation. And the compiler may decide, oh, well, I don't want to fuse here because I need the intermediate. And I eliminated a sub-expression somewhere else. And so the intermediate matters. Yeah, because you can refactor the math differently depending on how you want to approach that.
Starting point is 00:17:54 Yeah. Yeah. I guess then you go back to the same compiler. Or you have to document all the potential folding rules. I don't even know if that's possible. I don't know. Like, in Eastall, guys said that they were. was only a few things, but maybe the few things is, effectively, these are a few things,
Starting point is 00:18:08 but also there's a few things that is impossible to control. I have a proposal that I wrote up for HLSL to try to actually have math modes and have basically blocks where you can define different math behaviors in different blocks of code. It's inspired by what the metal shading language does, but the idea is really to give explicit control to users about, like, what's allowed where and how you can use different things. So we were discussing Matalesh's article. Yes. I think let's, let's, I just want to make sure that we give a fair shout out here that this is not what his article is about at all.
Starting point is 00:18:52 Mattouch has been working on a type safe units library for a really long time. And he's talking about what things can be caught at compile time versus what things have to be caught at runtime, et cetera. And anyhow. check out Matasha's library and check out this article. Yeah, it might be shorter to read than listen to us talking about it and not actually talk about it. And not actually talking about it. Although to be, we were here to talk about in Shalysel,
Starting point is 00:19:24 so I'm assuming we're somewhat staying on to the topic to some degree. Absolutely, we are. This is how my meetup also rolls. I have to always tell new people at my meetup. Welcome to my very formal and well-organized, user group. And everyone laughs. All right.
Starting point is 00:19:42 Let's do these next couple of news items quick because we've already gotten into the HLSL kinds of things. The next one is an article from the PVS Studio blog, which I love the PVS studio blog. There's always interesting things in here and often I can refer back to them when I'm doing training. This one is about the vibe coded project and basically, you know, what the AI can do around the performance here. What's the actual title of the article?
Starting point is 00:20:09 Check vibe code that acts like optimize C++, but is actually a mess. It sounds like my kind of article. I had missed this or hadn't had the time to read it, but I will definitely give it a look. I really enjoyed this article. This was really fun. I feel like there's so I'll out myself here that I'm generally a bit of a skeptic when it comes to AI coding tools. I do think that they're here to stay and they're not going away even if I I close my eyes and wish real heart. The thing that's interesting is, like, I don't think people understand their limits. And I do think there's a lot of people
Starting point is 00:20:49 who are talking about, like, using them to replace, you know, junior engineers or replace interns. There was an article in the ACM that it was published in their March issue, but posted online in February, that was redefining the software engineering profession for AI. It touches on some kind of related limitations of like what works and what doesn't. It's interesting to see like as people are starting to really become aware of the limitations of AI and the strain that the volumes of code people are producing is causing on teams,
Starting point is 00:21:26 it's giving me a little hope that our industry isn't completely doomed. I will not spend a lot of time going into it right now, but anyone who looks at my GitHub repositories right now, would see something kind of interesting because in the last two weeks I closed something like 40 issues across three open source projects and that's because I set up a little AI agent for myself
Starting point is 00:21:50 and I'm doing all the code reviews on it right and I'm telling it if I don't like the code reviews but it was a little like a let's say scary kind of experience because it was just like yep looks good merge merge merge merge merge oh wow I just closed 10 issues today issues that have been open for eight years. I just closed 10 of them just now.
Starting point is 00:22:12 And so I'm somewhere in the middle here because I've also seen the crap that it can generate, right? And I've seen where it can completely fail. I said, please enable warnings as errors. Complete failure. It enabled warnings as errors. And then it's like, now I will selectively disable all of the warnings that failed. No, wrong answer. I think the tricky thing here is that, you know, the current state of AI, like, they can't operate independently.
Starting point is 00:22:47 Like, there still needs to be a person involved in helping drive them. And I think that that's the piece that a lot of people miss. The Mesa project and the LVM project both had some trouble with people who didn't even know C. plus plus contributing patches that were thousands or tens of thousands of lines of code and being like, hey guys, I fixed this bug for you. And then being really upset when the community was like, yeah, we don't want this. And then on the other hand, you have people who are very experienced, who, you know, like you just described. Like you reviewed these patches. You set up an agent, you reviewed them. That's awesome. We actually also see some pretty experienced people who aren't really
Starting point is 00:23:42 reviewing patches that their LLMs are producing. Yeah, have to review the patch. Yeah. And then you're really just like offloading the work to someone else, right? It's like someone else has to do that work. I've also done an experiment of no human oversight, just let it run for like a week. And the code, I mean, it will make, probably will make something that works. But you're not. never going to want to maintain it. Yeah. The, the PBS studio blog, though, was pretty cool because, like, I think it hits on a really important point, which is that sometimes you can see something that looks very convincingly correct and isn't. And it takes a level of skill and experience and kind of the discipline to go
Starting point is 00:24:28 through and really look and understand what's happening to spot some of these things. And I think what made me think of the ACM article was that they talked about like how do you pass that knowledge and experience to junior engineers because you know we still need a pipeline for how we teach engineers to do this work and how we teach engineers to spot these things because we're not going to always be able to rely on you know all the gray-haired guys we're all we're all going to go off and retire so we keep raising our rates every year sorry I know I was going to I mean, people who follow my post on my rage tweets know that I'm clearly not on the side of AI. I have, like, sometimes the main news I found so far is the AI summary when you search something
Starting point is 00:25:15 because it is better than Google at parsing natural language. I'll give it that. The main problem to me is that AI, well, there's many problems, but if I have my two minutes of opinions. The first one is that it has someone said on another thing I was listening to the other day. it operates by the same rules as improv, right? Which is you can't say no, you have to say yes, and. So I have noticed that if you ask a question, the only way you get to know it's impossible
Starting point is 00:25:43 is because there's a primary source on like Stackoverflow or somewhere that people said, no, it can't be done. If there is no answer, it will make up one. I know because I was asking it some stuff in CMAC that apparently nobody ever tried before me, and I could tell because he invented three different variables that don't exist. Don't get me started on Seamake. Wait, yeah.
Starting point is 00:26:04 AI with Seamake or just Seamake by itself? Yes. I have written re-entrant C-Make. Oh, no. No, you stop. I've done some pretty horrible sins with C-Make. Yeah, I think the general vibe I'm getting is the less you look or care about the code generated,
Starting point is 00:26:29 or the less you know, know about it, the less expert you all, the more it's, again, it's convincing. And I've seen really the most people I've seen very interested is people are like, it's a code that I will never read ever, so I don't really care that it's bad. Or it's like, I can't even spot that it's not very good at what it does. I love using elements. It's so good at throwaway code. Yeah, I, I have this Git repository that's got 15, 20 years of history of just one-off Python scripts that I've written over the years where it's like, I needed a script to do something. And so I throw it in this get repository. I don't add scripts to that anymore. I just have an LLM generate me a new script.
Starting point is 00:27:03 Like, yeah. Because why not? Like, then I can throw it away. And if I forget that it exists, it's fine. Yeah, I think you have to be aware that it's not going to be maintainable and you're not going to learn anything in the process. And I think the second part, as you mentioned, the training new, for new engineer is a part that kind of like, is maybe sometime a bit too invisible to either people who decide about staffing or just assigned project. And even for engineers themselves, Like, maybe you don't realize that there is a lot of value in actually some junior or some even like experts trying to work on something they're not very good at that they've never done before and getting some learnings from that. And if they don't get them from there, where are they going to get them? I mean, as you mentioned, Jason, on the plus side, that means that, you know, if when we retire one day, maybe if we, if we're in short deed for cash, we can probably go back and say, I'm the part of the last generation that was actually.
Starting point is 00:27:58 basically trained, and I can fix this thing that you're like, not. It's going to be a billion per day. Thank you. Because money is cool anymore. But yeah, over than that, I don't know. I think there is clearly a thought that is not being followed through on that. Or maybe because the people that are using AI or pushing AI usage, both like the people who sell it and the companies that are actually using it, don't really have a huge stake in will we have engineers in 10 years, or maybe don't think they have a huge stake in that.
Starting point is 00:28:31 A lot of the economy is incredibly short-sighted. Yes. I think that's one of the risks in that sense. That the human leeway kind of helped, I think, counterbalance some of those shortcomings and short-sightedness. But, yeah. Yeah. Well.
Starting point is 00:28:49 All right. Let's talk about graphics programming, a topic that is fun. Yeah. You've mentioned HL-S-L. Like, can you just like give us a, you know, assume that your audience is like me, who doesn't know anything about this and give us some background? Sure. So I guess I'll give the, you know, short abbreviation, which is that HLSL kind of came into being in the early 2000s. And kind of the precursor to HLSL that was introduced
Starting point is 00:29:26 with DirectX8 was. something called DirectX Assembly. And what DirectX Assembly is is kind of what it sounds like. It was a virtual ISA that had an assembly language for programming early programmable hardware and GPUs. In those days, like, what was programmable in a GPU was very limited. Many of the devices didn't even have the ability to fetch additional instructions. So you were limited in how many instructions you could have by what you could fit in the iCash. and the iCash was populated by an external controller. So it was really much more of a, like,
Starting point is 00:30:02 you had an external controller that set up your GPU and then you just run it and hope it comes out the other side. As GPUs got more complicated, assembly programming wasn't really the ideal way to program them. And so HLSL came into being around the same time as NVIDIA's CG programming language and GLSL. And there are really three different but fairly similar languages that have kind of a lot in common. If your listeners are really interested, there were a couple of really great talks at the Kronos Shading Languages Symposium back in February.
Starting point is 00:30:38 The videos are on YouTube. I gave a talk with Stephen Perron from Google on kind of the history of HLSL and really went into some of the history of the compilers and kind of the main themes of where the language has kind of evolved over the years. And Randy Ross, who is the author of the book, the literal textbook on the GLSL programming language, he gave a really great talk titled GLSL Origins Opportunities, Origins, Observations, and Opportunities and talked about the whole history of shading languages going back before I was born. And it was like kind of fascinating to go through it all and see like how far computer graphics has come, but then also how far we have yet to go. Can I interrupt for just a quick, like, really silly question.
Starting point is 00:31:26 When you're saying early 2000s was the history of this with direct X8. I'm just trying to orient my brain here. So this is early 3D accelerated, or not talking about the first graphics cards that had 2D acceleration and trying to program what the 2D acceleration could do. Yeah, and the initial uses for HLSL were specifically for the vertex and, and, um, We call it in DirectX pixel in OpenGL parlance, it would be the fragment. And so basically what it is, you can mutate positions of vertices,
Starting point is 00:32:04 and you can mutate the final rendered color of the pixel or portion of the screen that you're drawing. Oh, yeah. I remember buying video cards at the time, and they said, now we've transformed in lighting or whatever it was called, I think, which I guess maps to do those two things to some degree. Yes. And the main, like the huge, the biggest innovation was really like in kind of the, I guess, late 2000s around the time that the PlayStation 3 and Xbox 360 were released was when you started seeing GPUs where they unified the pixel and vertex hardware into a single programmable unit that could do both. And that's really where shading languages got a whole lot more complicated and a whole lot more capable. And we started kind of moving away.
Starting point is 00:32:53 from shading languages as these really limited DSLs to really being closer to general purpose programming languages. And back then, this would have been specifically about actually programming what's on the screen, it was not being used for generic computation. So mostly, yes. That said, compute shaders for general computation have been around in HLSL and in GLSL for quite a long time. Okay.
Starting point is 00:33:20 I think really right around the time that the vertex and pixel hardware got unified was about the same time as you could start using what was effectively the vertex side of the hardware could really do general compute as well because it's just inputs and outputs. Yeah and I remember at least on one game that was really old in tech. We hacked around and I don't think I were the only one, hacked around the, availability in the API to do compute shaders by sending this amazing 2D textures to the pixel shader and then having an output 2D texture and basically what you do with it is math because every color is an input. Yep. And one of my running jokes about HLSL is that it's a floatly
Starting point is 00:34:07 typed programming language in that, you know, all data structures are really just some bundle of floats and so, you know, why not? They're just floatly typed. It's like JavaScript. No, that's not. I think of it kind of like, you know, C-Make is stringly-typed, and so HLSL is floatly-typed. On the note, you mentioned,
Starting point is 00:34:30 I think I have a kind of a good bouncing question on that one, because you mentioned GLSL and H-LSL. I myself did a lot of H-L-SL-L-Sel when I was in my previous job. Now I switched to Vulcan last year, and, you know, Vulcan Tutank comes with GLSL-Sl, so I did some GLSL instead. And I've noticed there is, I mean, if you want to do the easy,
Starting point is 00:34:50 or maybe cliche comparison, GLSL is trying to be C and HLSL is looking like it's trying to be more and more like C++. So I don't know if you have thoughts or like the divergence of opinions or vibes on the philosophy of the two languages, basic. Yeah, so what I will say, GLSL and HLSLA, they started in a very similar place. And in fact, like, a lot of the code between the two is like if you write an HLSL shader, of the code that you write in HLSL, you can actually take that exact code and write it and run it through the GLSL compiler. They share a lot of syntax. GLSL, I think, has kind of hit this point where it's very much a dying language. And I say that kind of in the sense of like Latin is a dying
Starting point is 00:35:40 language, not that it's going to go away, but that it's not evolving. And this is one of the things that I think has really been a challenge for GLSL is that they haven't had, you know, they haven't had developer interest in actually driving the language forward in quite a long time. And so if you look at the things that have been added to GLSL over the last decade, the vast majority of them are just kind of targeted additions to expose new hardware capabilities driven by hardware vendors who want to add things to Vulcan. HLSL isn't perfect on the other side of this, right? Like we've added some language features.
Starting point is 00:36:16 We did a big language release in 2021. We're working towards more. But honestly, most of our investments also have been around exposing hardware features. I would be remiss if I didn't mention there's a third language that's shown up in this space fairly recently, which is the slang programming language. And I will say, like, one of the things that I really appreciate about slang showing up into this space is that it's the first time that we actually have. some people who are really focusing on making a language better because I would love to make HLSL a better language but it's sometimes hard for me to convince my management that that's where we should spend effort because we're probably not
Starting point is 00:36:58 going to sell more licenses of Windows if HLSL is a better programming language and so it's really nice to see some you know innovation and interesting ideas coming into the space to the root of your question though like I think HLSL and GLSL really started, you know, along with NVIDIA's CG as being these very C-like DSLs, HLSL kind of started down the path of being more C++-like, in part because most of our users are C-plus-plus programmers, and so we were getting requests for more C-plus-like language features,
Starting point is 00:37:36 and in part because we decided at some point to base the HLSL compiler on Klang. And so a fair amount of things came in intentionally and a fair amount of things came in accidentally. And there's a bit of both going on. You know, one of our big thing with HLSL 2021 was adding C++ templates into HLSL. The thing that's probably the most awkward is that there's C++-98 templates. And so there's some weird limitations in them that, you know, the grizzled old people like me are like, oh, I remember when we used to to have to not have, or we used to always have to have spaces between double closing angle brackets. But, you know, a lot of our modern users are like, wait, what's going on here? This is a really weird compiler
Starting point is 00:38:25 error. Why doesn't this work? So we are slowly working on making HLSL more modern. We're bringing in, you know, we're looking at bringing in more C++ language features. I actually have a patch to fix the angle the double angle bracket so that we can you know let you put those next to each other and I have patches to add auto and a few other things that would be just really handy but it's a slow process I see do people like embed HLSL in their C++ programs like is there like extern HLSL or is it like how does what does this even look like I am totally like I have no idea how it's works the common flow for for HLSL programs and I think this is fairly common across pretty much all GPU programming these days so in the old days in open GL you would literally like take your GLS as a string and and you would
Starting point is 00:39:22 have a string that you would feed into an API that would compile it. DirectX and Vulcan and even metal have instead adopted this this model where you feed in a shader in a bytecode format and so you have an offline compiler. You can run the compiler online. It's not usually recommended because they're slow. But you have kind of a shader bytecode that comes in. And so the common thing is that you compile your shader when you compile your application or when you build your art assets and then you you kind of feed it in as a blob of data. One of the things that has led us down the path of being more C++ like though is that there's a lot of times, you know, you have a data structure that you're populating on the CPU side, it would be nice to use the same data structure
Starting point is 00:40:09 definition in your GPU code. And so by aligning HLSL more with C++, we really make it so that, you know, more of that is portable across the boundary. And so, like, you can define a struct in C++ that, you know, we don't have constructors, but we have, you know, instance methods and we have some of the other, the kind of the features that you would want. And you can literally just use that same header across both your HLSL and your C++. How does that work with like we were discussing, I believe, before we started recording, that you've got like eight-bit floating point numbers in HLSL, and no version of C++, by the standard supports a bit floating point at the moment.
Starting point is 00:40:56 So the bigger one is 16-bit float. So like we use those all over. Which we did get in C-Bus-126. Yeah. Yeah. We don't have 8-bit floats allowed as native types in HLSL. We actually don't have 8-bit integers either, which is kind of a weird historical thing. Oh, because you have the N-S-L, don't you?
Starting point is 00:41:19 Or GLSL. GLSL has a U-N-8, right? Yes, GLSL does. And the fact that we don't, like, irks my inner compiler engineer, because the reasoning is basically that, you know, a lot of GPUs, even modern GPUs, don't actually have 8-bit integer you know, math support. But if you
Starting point is 00:41:41 look at C, like, a lot of CPUs that C was designed for didn't have 8-bit integer support, which is why you have the usual arithmetic rules to solve that, right? Like, we clearly could have done something where we didn't have to remove the types, but
Starting point is 00:41:57 instead we removed them. The complicated thing, though, is like, So we have like these, you know, we have eight bit floats, but they're only used for actually the new ML operations that we've been adding this year. And so like they're pretty limited in what they can be used for. Like one of the tough things is that we do have data types like our ML data types that they actually don't have a known representation, even in our language. And so like we call them in the HLSL specification, we call them intangible types because like we don't have a known. size or a known memory layout for them. And so there's some restrictions on what you can and can't do with
Starting point is 00:42:39 them. But there's no way to map them into C++. There's just there's absolutely no way you could do that. How does this whole ecosystem relate to things like CUDA where people are doing generic GPU programming? Like are they, do they talk to each other at all or what? I mean, we we do work with a lot of people who work on CUDA. I kind of think that Kuta and I guess HIP would be AMD's equivalent. They're solving related but slightly different problems to what we're solving. The main difference being that when you compile a program for Kuta or for HIP, you're generally targeting,
Starting point is 00:43:21 if not a very specific GPU model, a specific family of GPUs. GPU isis have not stabilized in the way that CPU isses have. And so we all kind of take for granted in the CPU space that your x86 CPU that you have today still has 16-bit instruction decoders. And so it can run those old DOS applications compiled 30 years ago. In GPU land, even if you have,
Starting point is 00:43:48 if you have this year's AMD GPU, whether or not it has actual physical hardware support for a five-year-old AMD ISA is probably zero. Like it just doesn't. Like the architectures have evolved and changed much more rapidly and much more dramatically in GPUs. So what HLSL seeks to do is make it so that your DirectX game for DirectX9 runs on Windows 11 today. And the way that we do that is by having a virtual ISA that we target down to.
Starting point is 00:44:18 And then the GPU driver translates the virtual ISA into the native ISA at runtime. And so what we're really providing is a portable GPU language that works across a wide variety of hardware, with driver support that performs the final lowering. Thank you very much. That cleared up a lot for me. Yeah. It's a very weird space to be in. And there's like all sorts of interesting things around like weird tech debt that we have.
Starting point is 00:44:48 You know, we have shipped some of these things. And like, you know, the whole point of this existence is to make sure that applications that shipped 10 years ago still run exactly the same today. as they ran 10 years ago. And that introduces a whole mess of complications and challenges. So earlier we were discussing these problems with like floating point math. And you were talking about what the same expression and two different functions might generate two different results depending on reordering, whatever, right? And now you just got me curious.
Starting point is 00:45:23 What about with this intermediate translation layer and everything else that you have going on, does it guarantee that the same floating point math on AMD, the Intel and Invidia will generate the same result? No. Not at all. Okay. And we have, it's funny. So we have a test suite that we put up into the LVM project under the name, Offload Test Suite.
Starting point is 00:45:49 And what it is basically is we have a whole bunch of HLSL programs that we compile, we run data into them, and we look at the output. And anytime it's floating point math, like, we have to have either Epsilon or Alp-based comparisons on everything because the precisions are way different. And sometimes, like, one specific hardware vendor, who I won't name, their flagship GPU that they came out with recently, they on DirectX used an optimized, like, faster version of the hyperbolic tan function. And they did it because hyperbolic tan is frequently used
Starting point is 00:46:35 as an ML activation function. And so they sped it up for ML applications. But then they used the ML version on DirectX because we actually don't have any conformance tests that require specified precision on that function in our driver certification suite. So the new version of the function, it can be like 400, up off,
Starting point is 00:46:57 which is interesting. Can get some more... That sounds terrible. You know, I have frequently commented that the fun thing about working on a GPU compiler is that accuracy only kind of matters because, you know, we're just going to argue over whether or not your pink is pink enough. You know, it's all fine, right? It's fine. Everything is fine.
Starting point is 00:47:28 I mean, I've done not as the physicist or the scientist here, but a lot of work with physics simulation engines as the C++ expert, basically. And they have exhaustive regression test suites to make sure that any change does not change the output of the physics simulation. To the point that I'm not 100% positive, but I'm pretty sure that they actually use the same gold standard files. for all three platforms across all three major compilers. And then they have their delta set to something that they can tolerate, right?
Starting point is 00:48:04 And we get close enough answers on all the platforms across all the compilers that everyone is okay with this. And it sounds like, I don't know, your definition of close enough is different than their definition, perhaps. I mean, probably, but we do kind of the same thing. And in fact, in our test suite, we're just, starting to add graphics test cases. But one of the things that we do, rather than just a raw floating point compare on the graphics tests, we do like this color space transformation where
Starting point is 00:48:40 we translate the colors into a color space where the raw vector distance is more representative of human perception. So we're trying to actually gauge human, like, is the color perceptibly different rather than is the color off by too many bits in the floating point value. Right. There's math for that specifically, right? I mean, like that research has been done decades ago is what I'm trying to say. Yes. And the algorithm that we implement is not the best algorithm out there, but it's like from the 70s and it works pretty well. That's amazing. It sounds like a fascinating world, honestly.
Starting point is 00:49:18 This is, I spent my Christmas break like playing around with color space transformations when I wrote that code because it was just like, it was fun, you know. Yeah, we were speaking of talks and guy earlier. I think he has a talk called, like, you don't know anything about color, or I'm going to teach you that you don't know anything about color or something like that. Because the first you get into this thing, you're like, yeah, it's, you know, every color is like a $0 to $255 in red, green and blue, and I'm done. And then you're going into pain.
Starting point is 00:49:49 And a lot of fun surprises. Is color actually represented as floating point? in the GPUs? Yeah. What is the standard representation? I don't know that there necessarily is a standard. Like, GPUs have a lot of different modes that they can accept.
Starting point is 00:50:08 But RGBA, with each channel being a floating point value, is pretty standard. Float 8, float 16, or whatever. It depends. I mean, honestly, float 32 is probably the most commonly supported. Float 16s are pretty widely supported these days, but float 16s were more common in mobile devices until fairly recently when they've become pretty common across discrete devices as well.
Starting point is 00:50:36 The math is for the math is float 32 on every channel, but I think the actual input and output textures and whatnot, they're only like 8 bits per color. Yeah, yeah. So there's usually a reduction that happens in the rasterizer to reduce down from float 32 to whatever the target buffer format is. That's fascinating because I've kind of wondered like with again not knowing anything about this at all like what does it take for my software to support HDR if I buy a new HDR monitor then it sounds like it takes like they're already working in a huge color space
Starting point is 00:51:09 if it's RGBA float 32 that's way wider range than our monitors can display. Yeah and if you go back to like the old GPUs even like the early days of program mobile GPUs, basically all they were was 32-bit floating point. Like, everything was 32-bit floats. Sorry, I think I've derailed the conversation a little bit on color here, but... It's all right. I wanted to go back quickly because you said something that was interesting. You said that actually the request to have more C++ or go towards C++, and I mean,
Starting point is 00:51:38 since this is a Z++ podcast, I think this is an interesting question, both to me and hopefully to our audience, that, you know, users actually push for HLSL to be more like C++, which comes kind almost as a shock to me because having working in games for eight years after working in other domain that are way more friendly to C++, I've noticed that the closer you get to engine and graphics programmer, the more revulsion you get to C++ and the more people are like, no, no, no, no, no, no, C is where we peaked and we should not go back. So I'm surprised to hear that actually that might not be the case or maybe there's like a split somewhere there. I think there's probably a bit of nuance, which is that there are certainly people.
Starting point is 00:52:18 that we talk to that tell us that we've made a horrible mistake by adding templates. But there are other people who, you know, templates are actually a really good fit for GPU programming because they force instantiation. So on the other hand, like, you know, a more traditional like generics approach where specialization is optional basically doesn't work on a GP. Like you have to fully specialize all the way down and even like, like slang, which has generics with constrained interfaces. They have to specialize before they can generate final GPU code or it doesn't work. The nice thing about templates is that that just kind of comes free with how they're defined.
Starting point is 00:53:02 I think what we see in our users is a divide between people who want it to be C and people who want it to be more like C++ with an asterisk that there's even actually a divide in the C++ camp where there are some people who want HLSL to literally just become C++, and then there are other people who, like myself, think that if you add exceptions to HLSL, we've really, really gone the wrong way. There are certain features of C++ that would be so prohibitively bad for performance to implement on a GPU that, you know,
Starting point is 00:53:43 and this will change and evolve. As GPU hardware evolves, you know, what we can do on a GPU will change. But like today with the state of GPUs, what they are, if anyone tries to get me to add the virtual keyword to HLSL, I'm probably going to fight them to the death. Because like I don't know that there's any way that even on the most modern GPU architectures that you could handle the virtual keyword efficiently.
Starting point is 00:54:10 It would be an awful footgun. Exceptions are another one. Like there's no way we could do exceptions efficiently. Yeah, you don't want divergence in general. Right. For any loop, what has to be convergent or else? And exceptions, even if you don't use them, they cause constraints on the control flow graph that get to be really hard to generate good GPU code.
Starting point is 00:54:33 And so, like, there's some challenges around that. But I do think, like, we kind of have, we do have both camps. And I think one of the things that we're trying to do with HLSL is be really cautious about the features that we add. to HLSL being the ones that are kind of the most useful in GPU space, but also acknowledging that we do have a significant user base that, you know, things that the pinnacle of C++ plus was, you know, C with classes.
Starting point is 00:55:04 And that's okay. Like, you know, I think the pinnacle of debugging is printf. So, you know, I'm kind of partially there. Well, I guess in the sense it gives you the opportunity to, be like, what if we try to do C++ 2 or 3? I stopped counting how many people have tried to redo C++ by now. But like, if you were trying to give it another go, design-wise in 2020, whatever, six days today, well, what will we keep?
Starting point is 00:55:31 I guess another question, what would you add? Right? Because like right now, it seems to be mostly like we can look at the C++ plus like stand and say, okay, that yes, that, yes, that no, that, no, that, I think we can get a, I mean, that's first, the first time. Is there stuff that you don't have in C++ that you? I mean, I know there's stuff in Chedars that I would like in C++, like the dot XYZ, whatever, members, Swizzle is, I hate that I don't have that in C++.
Starting point is 00:55:56 Our vector types are pretty nice, aren't they? Yeah, I think the vector types is a good one. Like we have, I think, really good support for, you know, vectors up to four elements. Vectors beyond four elements get a little wonky, but we have them too. I think one of the things that I actually want to try to get involved in the C++ committee to help drive is like we actually could really use something like a constant valve parameter where like a fun like I want to be able to not have to declare a template but be able to say this function you know some variable or some some argument to it has to be const about and and be able to make it. error if it's not. This is something that comes in for us a lot because the virtual isases that we target often have requirements that certain arguments pass to them have to be immediates in the in the isa. And so it would be really great to have a higher level language feature where we could
Starting point is 00:56:57 just say, oh, when you call this function, we know that we have to be able to turn this into an immediate. So we know we want it to be constable and that would be super useful. Today we kind of get some of that by using template arguments and it's a little more awkward. That's definitely, I mean, on the C++ side, lots of things that people have asked for that kind of thing a lot. Yeah. Yeah. And I think, I don't know, I have some extensions that I wrote to the C pre-processor. And I don't know that most of them are useful for HLSL, but like, I have thought about like, it would be cool to actually have like typed macros and things because that would, you know, make some of our C-mindsetted people happier.
Starting point is 00:57:44 You know, we'll kind of, we'll keep poking at things and see, see where they shake out. I'm one of the areas where I'm most excited for HLSL to evolve, though, is around having, like, explicit annotations for convergence and divergence. For context for your users, or your listeners, if they're not familiar, like, you know, the way that we program GPUs, you know, you write a, you write a program is if you're working on a single, you know, operating on a single thread, a single piece of data. But what actually is happening underneath the hood is you're running this on a SIMB unit.
Starting point is 00:58:16 And what you're programming is effectively one line of that SIMD unit. And, you know, there's 63 other ones running the same instructions at the same time down the hardware. But we use masking to decide, you know, to handle control flow. So if you're one of your threads isn't participating in an operation, you mask it off. There are places where we require knowing that a value is consistent across all threads or that control flow is consistent across all threats. And we actually have no representation of that in the higher level language. And I would really love to kind of add that into the type system and really be able to make robust features around the convergence and divergence requirements so that we turn kind of a whole class of undefined behavior and runtime errors into compile time things that people can actually. But you've earlier in the conversation talked about some of the things that like, I mean,
Starting point is 00:59:13 these languages have been evolving for decades. And just for like maybe a parting word for our listeners who are working on their own language design right now, do you have like, like, I don't know some sort of like, how do you, how do you give the crystal ball, I guess, to the person who's designing a language from scratch today? I don't know. Comments? So I'll start, I'll plug, I gave a couple talks at the LVM developer meetings over the last couple of years, talking about some of the pain that we've experienced with HLSL. And those could be fun watches. I think one of the things that I think is probably most important that I've been kind of driving into the HLSL team culture is really acknowledging where we've made mistakes.
Starting point is 01:00:01 Because we've made a lot of mistakes. And I'm personally a slow learner. I tend to make mistakes a few times before I learn from them. But I think it's really important for people to acknowledge when you've made mistakes and learn from them and to kind of be able to talk about that. One of the things that I think if I could rewind and go back and be in the room when HLSL was first started, I would have really like screamed and screamed about is that we should have written a specification from the start.
Starting point is 01:00:31 So like for totally real, like I feel like, I feel like, that's a thing that people are like, oh, that sounds boring. But like, if you're writing a toy programming language and it's never going to go anywhere, like, fine, do whatever you're going to do. But if you think that your language is going to be something that you want other people to use, write a specification. Because there's a whole mess of things. Like, there's a bunch of behavior in HLSL that I honestly think that if someone had sat down and tried to write a specification for it, they would have realized that they can't specify it in a way that it. anyone could implement it.
Starting point is 01:01:07 Like, I think, like, the, we were talking earlier about the precise keyword. Like, I think that's a good example of, like, if you tried to actually write the language for how does this behave, you'd pretty quickly come to a point where it's like, does this even work? Like, like, how does this work? And, and you start seeing all the assumptions that you start baking into things. We've got quite a few language features in HLSL that are kind of this, this hodgepodge of accidental and intentional and they're not necessarily specifiable.
Starting point is 01:01:40 So one of my favorite examples that I'm picking on a whole lot lately because we're kind of driving a change for this is in the current production compiler, the overload candidate sets for functions are constructed differently based on whether the function name matches a built-in function or it's a user-defined function. And so we collect the candidates that's differently, and then that causes overload resolution to behave differently. Yeah. Which is subtle and weird. And that's before we even get to the fact that our overload resolution algorithm is not C++'s overload resolution algorithm. It's something else that uses a scoring system that itself is difficult to describe in a way that anyone would want to implement. And so, like, write a spec, write a spec, write a spec.
Starting point is 01:02:34 I think that that saves just a lot of headaches. The other one that I would throw out to as, like, advice for anyone building a compiler is test, test, test, test everything. And, like, I think, you know, probably the greatest, like, contribution to the compiler space that the LVM and Kling compiler's really brought in is, the excessive layers of serialization. Like if you look at playing, like, you know, you can dump the AST to text. You can dump the IR to text after every pass. You can dump the IR to text before you run any passes.
Starting point is 01:03:13 You can dump, you know, the machine IR to text as you get later in like all of these things are text serializable. And that makes it really, really easy to test each part of the compiler individually and separately. This is one of the things that, so my background, I never took a class in compilers in college. I was a game developer. My college degree is in computer game development.
Starting point is 01:03:37 I went off and worked at Midway Games and had my dream job there. I fell into compilers by accident. But what I can say is compilers are in many ways so much easier to work on than game engines because they're entirely deterministic. They're easy to test. You can just, and with the like the LVMR. where everything is serializable to text, you just dump it to text and move on.
Starting point is 01:04:00 And it's wonderful. So all of that is to say, write a spec, document your stuff, and test it, test it, test it, test it. That's cool. Just for clarification, is there another compiler than DXC or whatever Microsoft offers these days to compile a GLSL? Are you basically the only game in town
Starting point is 01:04:23 when it comes to pausing and generating from a JLSL? Oh, so that's a good question. So there's effectively a handful of HLSL compilers out there or HLSL-like compilers out there. So the original HLSL compiler was FXC. It's still in use in Windows, although we wish it wasn't. DXC is based on a 10-year-old fork of clang, which, if that sounds terrifying, it is.
Starting point is 01:04:53 And that's kind of the current production compiler. We're also like making a big push to add HLSL support into Klang. And so we actually have a fair amount of functionality in Klang proper for HLSL today. And we're continuously expanding that with the goal of deprecating and replacing DXC. There's also a number of other front ends out there that have some limited support for HLSL in one shape or another. So the slang compiler supports most of the, of HLSL up to the 2018 language variant, but does not support HLSL 2021, which is good because nobody should ever write their own C++ template engine.
Starting point is 01:05:38 And then there's another compiler out there by another company who I won't name that may make some video game stuff that you guys may have heard of or or may have played that has a programming language that is extremely similar to HLSL. And they have their own front end and their own compiler stack. And it is not HLSL, but it is extremely similar. Okay. Oh, we should probably wrap up. Thanks for coming on, Chris.
Starting point is 01:06:15 It's been great having you. Oh, thank you for having it. This has been a lot of fun. Yes. And since Keith passed on the curse too that you had to come, you feel free to name someone. on air or offline, that will then be forced, if possible, to come and be interviewed. I mean, I don't know about forcing people, but since I did mention slang a few times,
Starting point is 01:06:39 I will say Shannon Woods over at Nvidia is a wonderful person, and I'm sure she would have some wonderful things to talk about. They're doing some really interesting work in the shading space. Randy Ross is also heading up a bunch of stuff for Kronos right now. And he's been involved in organizing some of the shading language's work over there. So he's a super interesting person to talk to. And I'll give thoughts of some other people too because I think, you know, there's fun stuff happening around. It's just, you know, always figuring out who's doing what.
Starting point is 01:07:20 And of course, if you, the listener, would like to. either suggest someone or be yourself the guest of a future episode. We are building a backlog. It's always good to have a couple people ahead of us so we can release episodes on time and know what to interview. So feel free to reach out to us for your favorite ways. But all our favorite ways of reaching out to us, by the way, Jason. I'm going to have one back at you.
Starting point is 01:07:49 How does one get in touch with us? That is a spectacular question that I have not given a lot of thought to. Let's see, I know that I can be DM'd on Reddit or any social media platform specifically, and you're pretty much most places as well. Yeah, yeah, yeah, yeah. For better or worse, I am still on X.com, the everything up for only Twitter, and I think I still have my DMs open there. Although, sometimes it ends up in the weird spam filter,
Starting point is 01:08:17 and I only notice it like three months after you were trying to talk to me at a conference. But, you know, let's say for the short answer till we work out a better way, DM one of us on some platform. See you next month.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.