u/Longjumping-Cup-8927

▲ 6 r/vulkan

How I am supposed to restrict bindings across shaders in the same file for slang?

I am a little confused on what is broken. I thought slang compilation was supposed to "handle the bindings." so here I would of expected that ubo would of been included in only the vertex spirv, and texSampler would only be included in the fragment spirv. I am sure that there is probably something I need to do explicitly here, but I was sold on slang auto-magically handing these types of things. I am new to graphics programming and initially followed the old tutorial to completion then wanted to try porting over to slang. Any help is appreciated, as i have been digging through the slang and vulkan documentation for a while and its been hard to figure out how it all comes together without a real example.

slang file :

struct MatrixParameters{
float4x4 model;
float4x4 view;
float4x4 proj;
}
struct Vertex{
float3 position;
float3 color;
float2 uv;
}
struct VOut
{
float4 position : SV_POSITION;
float3 fragColor;
float2 fragTexCoord;
}
ConstantBuffer<MatrixParameters> ubo;
[shader("vertex")]
VOut main(Vertex input)
{
VOut output;
output.position = mul(ubo.proj, mul(ubo.view, mul(ubo.model, float4(input.position, 1.0))));
output.fragColor = input.color;
output.fragTexCoord = input.uv;
return output;
}
uniform DescriptorHandle<Sampler2D> texSampler;
[shader("fragment")]
float4 main(VOut input) : SV_TARGET
{
float4 outColor = float4(input.fragColor * texSampler.Sample(input.fragTexCoord).rgb, 1.0);
return outColor;
}

c++ program file :

// CREATING DESCRIPTOR SET LAYOUT
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr;

VkDescriptorSetLayoutBinding samplerLayoutBinding{};
samplerLayoutBinding.binding = 1;
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
samplerLayoutBinding.descriptorCount = 1;
samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;

std::array<VkDescriptorSetLayoutBinding, 2> bindings = { uboLayoutBinding, samplerLayoutBinding };

VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
layoutInfo.pBindings = bindings.data();

vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &outDescriptorSetLayout)
...
slangModule->getDefinedEntryPoint(0, vertexEntryPoint.writeRef());
slangModule->getDefinedEntryPoint(1, fragmentEntryPoint.writeRef());

slangResources.mpSessionInstance->createCompositeComponentType(
componentTypes.data(), // {slangModule, vertexEntryPoint, fragmentEntryPoint }
componentTypes.size(),
composedProgram.writeRef(),
diagnosticBlob.writeRef());

composedProgram->getEntryPointCode(
0,
0,
spirvCode,
diagnosticBlob.writeRef()
);
VkShaderModuleCreateInfo shaderModuleCreateInfo{};
shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfo.codeSize = spirvCode->getBufferSize();
shaderModuleCreateInfo.pCode = reinterpret_cast<const uint32_t *>(spirvCode->getBufferPointer());
VkShaderModule vertexModule;
vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &comboModule);



composedProgram->getEntryPointCode(
1,
0,
spirvCode2,
diagnosticBlob.writeRef()
);
VkShaderModuleCreateInfo shaderModuleCreateInfoFr{};
shaderModuleCreateInfoFr.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfoFr.codeSize = spirvCode2->getBufferSize();
shaderModuleCreateInfoFr.pCode = reinterpret_cast<const uint32_t *>(spirvCode2->getBufferPointer());
VkShaderModule fragmentModule;
vkCreateShaderModule(device, &shaderModuleCreateInfoFr, nullptr, &fragmentModule;

ERROR output :

validation layer: vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[0] shader [VK_SHADER_STAGE_VERTEX_BIT] uses descriptor [Set 0, Binding 1, variable "ubo"] (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) but the VkDescriptorSetLayoutBinding::stageFlags was VK_SHADER_STAGE_FRAGMENT_BIT.
(VkDescriptorSetLayout from VkPipelineLayoutCreateInfo::pSetLayouts[0]).
The Vulkan spec states: If a resource variable is declared in a shader and layout is not VK_NULL_HANDLE, the corresponding descriptor set in layout must match the shader stage (https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkGraphicsPipelineCreateInfo-layout-07988)
validation layer: vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[1] shader [VK_SHADER_STAGE_FRAGMENT_BIT] uses descriptor [Set 0, Binding 0, variable "globalParams"] (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) but the VkDescriptorSetLayoutBinding::stageFlags was VK_SHADER_STAGE_VERTEX_BIT.
reddit.com
u/Longjumping-Cup-8927 — 4 days ago
▲ 18 r/vulkan

Mulithreading Shader Compilation?

I was reading this tutorial https://vkguide.dev/docs/extra-chapter/multithreading/ and it claims that you can compile shaders on a background thread and avoid hitching. Is this true? Are there any drawbacks to this approach?

"For compiling pipelines, vkCreateShaderModule and vkCreateGraphicsPipeline are both allowed to be called from multiple threads at once. A common approach for multithreaded shader compilation is to have a background thread dedicated to it, with it constantly looking into a parallel queue to receive compilation requests, and putting the compiled pipelines into another queue that then the main renderthread will connect to the simulation. This is very important to do if you want to have an engine that doesn’t have a lot of hitching. Compiling shader pipelines can take a very long time, so if you have to compile pipelines at runtime outside of a load screen, then you need to implement such a multithreaded async compile scheme for your game to work well."

reddit.com
u/Longjumping-Cup-8927 — 11 days ago

Keeps reconnecting even when automatic is disabled!

every time I try to toggle off the vpn on my iPhone, NordVPN just turns itself back on. I disable connect on demand in the settings and then later nord just turns connect on demand back on. In the app I have automatic connect disabled as well.

Can we get a setting that turns off all background processes of Nord and forfeits all activation and disabling of the vpn to the device setting?

maybe there is a way to fix it, but the systems like disabling automatic connection don’t seem to work as advertised. so it might just be that some of these are bugged.

reddit.com
u/Longjumping-Cup-8927 — 11 days ago

Flash Thompson, Spider Fan targeting Oak Street Inkeeper with both?

what would happen if an untappped [[Oak Street Inkeeper]] were targeted by an opponents [[FlashThompson, Spider Fan]] by both the tap and untap modes? would the hexproof from being tapped prevent the second mode from untapping it?

reddit.com
u/Longjumping-Cup-8927 — 2 months ago

False Orders Multiplayer Question?

[[False Orders]] is a weird card because it bypasses regular blocking rules. in multiplayer there are multiple defending players. can I make a creature from one defending player block a creature that is attacking a different defending player.

“Cast this spell only during the declare blockers step.Remove target creature defending player controls from combat. Creatures it was blocking that had become blocked by only that creature this combat become unblocked. You may have it block an attacking creature of your choice.”

edit:

adding some additional info here since I think some people are confused by how this card works. (A couple people said no and then soon after deleted their post). This card bypasses the normal blocking restrictions imposed when declaring a blocker. For example an unblockable creature can be blocked using this card. Whats unclear is that in multplayer formats with multiple defending players there doesn’t seem to be a stated restriction as far as I can tell that would prevent *False Orders* from allowing a creature from one defending player to block a creature attacking a different defending player.

*Will update conclusion if anyone finds anything to the contrary.

=========== CONCLUSION =========

In a multiplayer game you can target the creature of one defending player and choose an attacking creature that’s attacking a different defending player to have the target creature block and it will in fact block

========== Rules and Explanations =======

802.4. If more than one player is being attacked, controls a planeswalker that’s being attacked, or protects a battle that’s being attacked, each defending player in APNAP order declares blockers as the declare blockers step begins. (See rule 101.4 and rule 509, “Declare Blockers Step.”) The first defending player declares all their blocks, then the second defending player, and so on. 

802.4a A defending player can block only with creatures they control. Those creatures can block only creatures attacking that player, a planeswalker that player controls, or a battle that player protects.

802.4a is a subsection to 802.4 a ruling on of “declaring” blockers in multiplayer and so does not affect which attacking creature you get to choose with “False Orders.”

Interestingly the rules does address a similar situation where a creature enters the battlefield blocking (after blockers are declared).

  • 509.4a If the effect that puts a creature onto the battlefield blocking specifies it’s blocking a certain creature and that creature is no longer attacking, the creature is put onto the battlefield but is never considered a blocking creature. The same is true if the controller of the creature that’s put onto the battlefield blocking isn’t a defending player for the specified attacking creature.

TLDR for 509.4 is that a special case rule was needed for creatures that are put in play defending a creature that was not attacking a player to make it not block that creature. 

Blocking restrictions are only done as part of the turn-based action “declaring blockers.” The process of declaring blockers is where legal restrictions are applied. See rules 509.1 and 509.1a-509.1i.

*see 509.1a “…For each of the chosen creatures, the defending player chooses one creature for it to block that’s attacking that player”

After blockers are declared the active player gets priority (509.2).  This is when a player is able to cast “False Orders.” This is significant because no restrictions exist at this point to restrict the players choices other than what the card says “an attacking creature of your choice.”

Now some additional supporting evidence is  509.3, where it makes distinction between “declared as a blocker” and “a blocker as the result of an effect” where in this case the rules are accounting for cards like “false orders” that circumvent the process of “declaring a blocker” to make something block.

Relevant rulings listed below:

  1. Declare Blockers Step

509.1. First, the defending player declares blockers. This turn-based action doesn’t use the stack. To declare blockers, the defending player follows the steps below, in order. If at any point during the declaration of blockers, the defending player is unable to comply with any of the steps listed below, the declaration is illegal; the game returns to the moment before the declaration (see rule 733, “Handling Illegal Actions”).

509.1a The defending player chooses which creatures they control, if any, will block. The chosen creatures must be untapped and they can’t also be battles. For each of the chosen creatures, the defending player chooses one creature for it to block that’s attacking that player, a planeswalker they control, or a battle they protect.

509.1b The defending player checks each creature they control to see whether it’s affected by any restrictions (effects that say a creature can’t block, or that it can’t block unless some condition is met). If any restrictions are being disobeyed, the declaration of blockers is illegal.

A restriction may be created by an evasion ability (a static ability an attacking creature has that restricts what can block it). If an attacking creature gains or loses an evasion ability after a legal block has been declared, it doesn’t affect that block. Different evasion abilities are cumulative.

Example: An attacking creature with flying and shadow can’t be blocked by a creature with flying but without shadow.

509.1g Each chosen creature still controlled by the defending player becomes a blocking creature. Each one is blocking the attacking creatures chosen for it. It remains a blocking creature until it’s removed from combat or the combat phase ends, whichever comes first. See rule 506.4.

509.1i Any abilities that trigger on blockers being declared trigger. See rule 509.2a for more information.

509.2. Second, the active player gets priority. (See rule 117, “Timing and Priority.”)

509.2a Any abilities that triggered on blockers being declared or that triggered during the process described in rule 509.1 are put onto the stack before the active player gets priority; the order in which they triggered doesn’t matter. (See rule 603, “Handling Triggered Abilities.”)

509.3. Triggered abilities that trigger on blockers being declared may have different trigger conditions.

509.3a An ability that reads “Whenever [a creature] blocks, . . .” generally triggers only once each combat for that creature, even if it blocks multiple creatures. It triggers if the creature is declared as a blocker. It will also trigger if that creature becomes a blocker as the result of an effect, but only if it wasn’t a blocking creature at that time. (See rule 509.1g.) It won’t trigger if the creature is put onto the battlefield blocking.

Since there isn’t a restriction like 509.4a for effects that rearrange blockers like “False Orders” effect, it means that in this obscure case a different defending players creature can be used to block a creature attacking a different player.

Special Note About 802.2a:

802.2a ...If a spell or ability refers to both an attacking creature and a defending player, then unless otherwise specified, the defending player it’s referring to is the player that creature is attacking, the controller of the planeswalker that creature is attacking, or the protector of the battle that player is attacking

This rule specification is on who the defending player is. It is not a specification on what creatures are considered “attacking” only a clarification on which player is considered defending. This really just means that you can’t target a creature from a non-defending player (in edh all players except the attacking player are considered defending players).  However this does have implications in different game modes where you can only attack to the left or right for example.

reddit.com
u/Longjumping-Cup-8927 — 2 months ago