Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

2787 Excellent

About WFP

  • Rank

Personal Information

  • Website
  • Role
    Business Development
    Technical Director
  • Interests


  • Twitter

Recent Profile Visitors

9229 profile views
  1. 🤦‍♂️ 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!
  2. For anyone interested in tracking this issue, there is a ticket open here: https://github.com/microsoft/DirectXShaderCompiler/issues/2236
  3. 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.
  4. 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.
  5. 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!
  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. 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 😃
  8. 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.
  9. 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!
  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.
  • 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!