@@ -94,28 +94,26 @@ uint32_t RenderingDXIL::patch_specialization_constant(
9494 const uint64_t (&p_stages_bit_offsets)[D3D12_BITCODE_OFFSETS_NUM_STAGES],
9595 HashMap<RenderingDeviceCommons::ShaderStage, Vector<uint8_t>> &r_stages_bytecodes,
9696 bool p_is_first_patch) {
97- uint32_t patch_val = 0 ;
97+ int64_t patch_val = 0 ;
9898 switch (p_type) {
9999 case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT: {
100- uint32_t int_value = *((const int *)p_value);
101- ERR_FAIL_COND_V (int_value & (1 << 31 ), 0 );
102- patch_val = int_value;
100+ patch_val = *((const int32_t *)p_value);
103101 } break ;
104102 case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL: {
105103 bool bool_value = *((const bool *)p_value);
106- patch_val = (uint32_t )bool_value;
104+ patch_val = (int32_t )bool_value;
107105 } break ;
108106 case RenderingDeviceCommons::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT: {
109- uint32_t int_value = *((const int *)p_value);
110- ERR_FAIL_COND_V (int_value & (1 << 31 ), 0 );
111- patch_val = (int_value >> 1 );
107+ patch_val = *((const int32_t *)p_value);
112108 } break ;
113109 }
114- // For VBR encoding to encode the number of bits we expect (32), we need to set the MSB unconditionally.
115- // However, signed VBR moves the MSB to the LSB, so setting the MSB to 1 wouldn't help. Therefore,
116- // the bit we set to 1 is the one at index 30.
117- patch_val |= (1 << 30 );
118- patch_val <<= 1 ; // What signed VBR does.
110+
111+ // Encode to signed VBR.
112+ if (patch_val >= 0 ) {
113+ patch_val <<= 1 ;
114+ } else {
115+ patch_val = ((-patch_val) << 1 ) | 1 ;
116+ }
119117
120118 auto tamper_bits = [](uint8_t *p_start, uint64_t p_bit_offset, uint64_t p_tb_value) -> uint64_t {
121119 uint64_t original = 0 ;
@@ -169,13 +167,13 @@ uint32_t RenderingDXIL::patch_specialization_constant(
169167
170168 Vector<uint8_t > &bytecode = r_stages_bytecodes[(RenderingDeviceCommons::ShaderStage)stage];
171169#ifdef DEV_ENABLED
172- uint64_t orig_patch_val = tamper_bits (bytecode.ptrw (), offset, patch_val);
170+ uint64_t orig_patch_val = tamper_bits (bytecode.ptrw (), offset, ( uint64_t ) patch_val);
173171 // Checking against the value the NIR patch should have set.
174172 DEV_ASSERT (!p_is_first_patch || ((orig_patch_val >> 1 ) & GODOT_NIR_SC_SENTINEL_MAGIC_MASK) == GODOT_NIR_SC_SENTINEL_MAGIC);
175- uint64_t readback_patch_val = tamper_bits (bytecode.ptrw (), offset, patch_val);
176- DEV_ASSERT (readback_patch_val == patch_val);
173+ uint64_t readback_patch_val = tamper_bits (bytecode.ptrw (), offset, ( uint64_t ) patch_val);
174+ DEV_ASSERT (readback_patch_val == ( uint64_t ) patch_val);
177175#else
178- tamper_bits (bytecode.ptrw (), offset, patch_val);
176+ tamper_bits (bytecode.ptrw (), offset, ( uint64_t ) patch_val);
179177#endif
180178
181179 stages_patched_mask |= (1 << stage);
0 commit comments