Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Everything posted by WFP

  1. I'm testing out DXC to compile HLSL files into SPIR-V, but have run into an issue on a seemingly simple shader. The shader compiles and runs fine using glslangValidator with the -D flag (HLSL input), but when trying to compile it with DXC, I get the following error message: Is there a flag or option I've missed to force DXC to output a multiple-of-4 result? With this requirement, I would have assumed it would have done that by default, but that obviously isn't the case. Below are the two commands I'm trying to get to act the same. As stated, the first command produces the expected result and everything runs fine. The dxc line gives the issue. (And I run these separately - they're posted together below for quick reading, but they do not run sequentially and overwrite each other in practice). C:/VulkanSDK/ -e main -V -D Basic_PushConstant_HLSL.frag -o basic_push_constant_ps.spv C:/"Program Files (x86)"/"Windows Kits"/10/bin/10.0.17763.0/x64/dxc.exe /Zi /spirv /fspv-target-env=vulkan1.1 /E"main" /Od /Fo"basic_push_constant_ps.spv" /T"ps_6_0" /nologo Basic_PushConstant_HLSL.frag The shader is below. Nothing fancy, just drawing colored quads on the screen. [[vk::push_constant]] cbuffer PConsts : register(b2) { [[vk::offset(8)]] float cb_push; }; struct PixelIn { float4 posH : SV_Position; float3 color : COLOR; float2 texcoord : TEXCOORD; }; float4 main(PixelIn pIn) : SV_Target0 { float3 color = pIn.color * saturate(cb_push + 0.2f); return float4(color, 1.0f); } Thanks!
  2. 🤦‍♂️ Thank you!!! For the longest time I've only supported SM 5.0 for compatibility reasons, and had nearly forgotten that 5.1 added the templated ConstantBuffer type. Since DXC is 6.0 and up, of course I should have updated to the new syntax. That's what I was missing. Changing the code as shown below fixes the issue, with all attributes properly in use and no warnings or errors. Thanks again!
  3. For anyone interested in tracking this issue, there is a ticket open here: https://github.com/microsoft/DirectXShaderCompiler/issues/2236
  4. Thanks, I was waiting to open a new issue just in case I had accidentally missed a build option or something, but the more combinations I try, the more I think I should just go ahead and do that. I'll post the link to the issue here once it's open, in case it helps anyone else in the future.
  5. A few more things I've tried, in case it helps. - Tried switching to the 32-bit dxc.exe. - Tried this with the most recent dxc build from Appveyor - Tried forcing the read in code size to a multiple of 4 by padding with zeros - this causes a new error saying that the SPIR-V magic number is invalid.
  6. Thanks! I'd seen the MSDN page (https://docs.microsoft.com/en-us/windows/desktop/direct3d12/hardware-support) before, but it's great to have an additional resource to turn to for referencing actual hardware support. That combined with Steam's hardware survey seems like a really handy combination. And yeah, I probably should've specified that by bindless I was more specifically referring to SRVs. I can see it as useful for CBVs and UAVs, but so far haven't had issue working even within their low tier limits.
  7. Main question: How are you all nowadays abstracting resource binding between D3D12 and Vulkan? The graphics backend for my engine was initially written in Direct3D 12, and the abstraction layer very closely mimicked that with the goal of being as thin as possible (many calls basically amount to passthroughs). I've recently started porting my graphics backend to Vulkan. I've actually found this to be very straightforward for the majority of the effort, the two largest differences of course being render target/framebuffer management and resource binding. Of those two topics, resource binding is the main area I have hang-ups on for best abstraction and implementation, and that is where I'm hoping for advice. I've got this working "well-enough", which is to say I can bind resources and they get where they need to go, but the setup I have feels brittle, for lack of a better word, and I consider it to be very much in a rough draft type of state. I've read a few posts here on the topic, but many are a few years old at this point. I'm sure best practices have evolved over time as people become more accustomed to working with both APIs. For example, this post is almost three years old to the date (https://www.gamedev.net/forums/topic/678860-descriptor-binding-dx12-and-vulkan/). Secondary question: Mostly out of curiosity, how universal is support for bindless textures? More specifically, if the targets are PC and current generation consoles, can a bindless model be fully adopted, or are there any platforms in this set that do not support it? Last question: What are your thoughts on a root constant/push constant versus a draw ID vertex buffer? I implemented this type of side-along vertex buffer a long while back in the engine's D3D11 days in order to bind one large constant buffer and index into it with an instance offset at draw time, and have honestly just not revisited its necessity until I reviewed it while making notes before I started working on the Vulkan port. Basically, I bind the actual vertex buffer and additionally to a known slot bind a draw ID vertex buffer that is just incrementing 0-4095 where the index is accessed through the startInstanceLocation parameter of draw calls. It certainly works well enough and keeps the number of setConstantBufferView-type calls very low, but it seems a root/push constant would achieve the same outcome without the additional vertex buffer being bound. Honestly, I should probably just profile and see, but figured I'd ask for general consensus while I was here Thanks for your time!
  8. Thanks for the reply, that's a helpful way to think about it. I've actually been working on a way to remove the concept of a descriptor heap directly, and instead submit ResourceBinding structs (several at a time as a list), and have some metadata that's stored at root signature and PSO creation time sort out the right place for them to land. It helps keep the API a little smaller/cleaner, and also lets me do a little bit of basic validation to ensure the root signature (pipeline layout for Vulkan) matches the incoming bindings. It seems like this is going to be an even better approach since it can also obscure the underlying details of descriptor pools/sets. I'll keep at it and see how it goes. And thanks for the tip regarding the draw ID 😃
  9. Thank you, that is helpful! I'm fairly certain bindless is a safe bet for the other console, as well, since it's supposed to be Tegra X1-based, and bindless textures are specifically called out on this page: https://shield.nvidia.com/blog/nextgenx1.
  10. WFP

    Copy pointer to aiScene

    I haven't read through the Assimp internals or documentation in a while, but from what you're describing, I'm guessing that your aiScene pointer becomes invalid when the Assimp::Importer goes out of scope. If that's the case, you'll need to store the Assimp::Importer somewhere until you're done using it.
  11. Try running it with the -srgb flag.
  12. The root signature is what controls visibility and register assignment in D3D12. In your specific case for constant buffers, the D3D12_ROOT_DESCRIPTOR contains a ShaderRegister variable for you to fill out that will match what you type in your shader code as cbuffer MyCB: register(b#). For example, if you set ShaderRegister to 5, then you would declare cbuffer MyCB: register(b5). The D3D12_ROOT_PARAMETER (of which the root descriptor is a unioned member of) has a ShaderVisibility member that controls which stages of the pipeline the parameter is visible to. You can either set the visibility to ALL, or to individual stages and use duplicate (with different stage) entries in the root signature. See here: https://msdn.microsoft.com/en-us/library/windows/desktop/dn913202(v=vs.85).aspx#visibility In your case, you can give your shared constant buffers ALL visibility and set them once using SetGraphicsRootConstantBufferView, or you can give your shared constant buffers duplicate entries with specific visibilities (VERTEX and PIXEL) and set them each with separate calls to SetGraphicsRootConstantBufferView. The link above mentions this, but some hardware handles ALL differently and is less efficient than setting individual stages, while other hardware will have no extra cost for setting ALL. Keep in mind general best practices for root signatures when deciding on a route - keep the root signature as small as possible, with items that change more frequently towards the beginning. Root constant descriptors take 2 DWORDS each, so can start to grow your root signature quickly if you're not mindful. More documentation that you might find helpful: https://msdn.microsoft.com/en-us/library/windows/desktop/dn859357(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn986747(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn879476(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn879482(v=vs.85).aspx
  13. Yes to the first part, not exactly (but close) to the bulleted question. If you can swing it, you should consider using the same or similar allocators for the same command lists. For example, let's say you're doing deferred rendering and are drawing some number of items. Your pass to fill the gbuffer may take (for example's sake) 200 calls to various functions on the command list, which are written to the allocator. Your shadowmap pass has to be run for each shadow-casting light, so you'll have somewhere in the neighborhood of 200 * numLights entries in the command list, and therefore that allocator. If in a subsequent frame, you use the allocator you initially used for the gbuffer pass for the shadow map pass, that allocator will grow to the worst-case scenario size, i.e., the size required by the shadowmap pass. If instead you keep that allocator designated for gbuffer stuff only, it'll only be sized enough for your worst-case gbuffer pass, so could save on your overall memory budget. To answer whether you need to know the size of the command list before calling CreateCommandList, not precisely, but it's helpful to have some idea of how the command list will be used so you have a ballpark idea of how it will affect the allocator bound to it. Keep them to a minimum, but don't dig yourself into a hole. You can reuse an existing command list to write into a separate allocator than the one you initially created it with while the initial allocator's content is being consumed by the GPU. You still must set and track your fence values to be sure that the GPU is done with the allocator you're about to reset and reuse. You should create enough to cover your maximum latency, but if it comes down to it, you still must be able to block and wait for the GPU to finish it's work if all the command allocators are occupied. This is like the pool of allocators @galop1n mentioned in his post.
  14. Any chance the working directory is being changed? Can you post your log / crash output here? Could you add a log statement before compiling the shaders (in the loadAndCompileShaderFile function) to print out the working directory?
  15. WFP

    The "Sky" is too short!

    You could use them, or keep your sky dome and in the vertex shader do something like: //... some code posH = mul(inputPos, viewProjMtx); // this is your SV_Position output posH.z = posH.w; // when the divide by w occurs, this will make the depth 1.0 (far plane) //... whatever else You could also just use a full-screen triangle or quad and use the same "push it to the far plane" logic. Then in the pixel shader, color it based off the y component of a view ray (a ray from starting at the camera and extending out into the scene) - all depends on how fancy you want to get. If you stick with the dome, make sure you only transform it by the camera's position, and not rotation - otherwise the entire sky will spin as the camera spins.
  16. WFP

    'Shader resource view' problem

    This warning usually means that the resource you're using in **SetShaderResources is bound as a render target. The D3D11 runtime will remove it for you and give you a warning, but for correctness (warning-free output) you should either overwrite what's bound to the output merger before setting the shader resources OMSetRenderTargets(1, &newRTV, nullptr); or clear what's currently bound by setting it to null: OMSetRenderTargets(0, nullptr, nullptr);
  17. WFP

    The "Sky" is too short!

    To expand just a bit on Kylotan's accurate response - in your specific application, what does a "unit" mean? In other words, is the value "1 unit" representative of 1 meter, 1 centimeter, or some other value altogether? If 1 unit = 1 cm, then a sky 1000 units away would be 10 meters away. Alternatively, if your app takes place entirely on the ground and the sky is supposed to look infinitely far away, you could always force the geometry to the far plane in the vertex shader and have its position transform with the camera position to give the illusion that it's so far away it doesn't move when the camera moves a bit.
  18. I won't have time to do a full install and all that, but if you can grab a capture with RenderDoc (or a few captures with different deficiencies showing), I might be able to step through the shader that way and see what could be going on. Can't promise when I'll have a lot of focused time to sit down with it, but I'll try to as soon as I can.
  19. Admittedly, I've done very little with stereo rendering, but perhaps this offset needs to be accounted for in your vertex shader? float4 stereo = StereoParams.Load(0); float separation = stereo.x * (leftEye ? -1 : 1); float convergence = stereo.y; viewPosition.x += separation * convergence * inverseProj._m00; The view ray you create in the vertex shader may need to be adjusted similarly to align correctly. Just kinda guessing at the moment
  20. For thoroughness's sake, would you mind switching them back to non-negated versions and seeing if that helps? Could you also test with the original rayLength code? Does the game use a right- or left-handed coordinate system?
  21. Is there a particular reason you're negating these values? traceScreenSpaceRay(-rayOriginVS, -rayDirectionVS
  22. Crap! Sorry again for the delay, let's see if we can get you sorted out If this is a full-screen pass, I would suggest trying the position reconstruction from my other post and see how that works out for you. Also - are you sure that the water surface is written to the depth buffer? If the game draws it as a transparent surface, it may disable writes when drawing it. That would mean you're actually using the land surface underneath the water as the reflection start point. I would first try using the projected view ray I mentioned and see if that gets you anywhere: o10 = mul(modelView, v0.xyzw); //viewPosition o10 = float4(o10.xy / o10.z, 1.0f, o10.w); If you're doing the SSR as part of the water shader itself, i.e. at the same time as drawing the transformed water geometry, you should be able to calculate the view space position and pass it through to the pixel shader, then use that value directly instead of combining it with a linearized depth value. Let me know if any of that helps.
  23. At first glance, this seems incorrect to me: float3 rayOriginVS = viewPosition * linearizeDepth(depth); Can you tell me what value you're storing in viewPosition? In my implementation, that line describes a ray from the camera projected all the way to the far clip plane. In the vertex shader: // project the view-space position to the far plane vertexOut.viewRay = float3(posV.xy / posV.z, 1.0f); Using that multiplied by linearized depth lets you reconstruct view-space position in the pixel shader, which is what you need for rayOriginVS. MJP's entire series is a great resource on reconstructing position from depth, but the last post, https://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/, is closest to what I use for most cases. I don't own/haven't played the game, so this is strictly a guess, but to me it looks like the rocks (as well as the boat and fisherman in it) are billboarded sprites. If that's the case, there's a good chance they aren't even being written to the depth buffer, which means there would be nothing for the ray-tracing step to detect. Are you able to pull a linearized version of the depth buffer that shows what is and isn't actually stored in it? That could be really helpful for debugging . P.S. I think you might be the same person that was asking about this (Dirt 3 mod + 3DMigoto) on my blog post on glossy reflections. Sorry I never got back to you - to be completely honest, I got really busy with a few things around then and forgot over time.
  24. Yeah, I think something with the site updates may have messed up the gallery link. You can find them by going to my profile and clicking the Albums tab, or use this link:
  25. On mobile right now, but briefly - the HLSL compiler will spit out the same intermediate bytecode regardless of what your system specs are. When your application calls a D3D function to load the shader from the pre-compiled bytecode, it will be compiled again in a vendor-specific way before actually being used. So to answer your question - you can compile a shader on one machine with a dedicated GPU and run it on another machine with an integrated GPU just fine.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!