1313from mock_renderdoc import (
1414 ActionDescription ,
1515 ActionFlags ,
16+ ConstantBlock ,
1617 DepthStencilState ,
18+ Descriptor ,
1719 MockPipeState ,
1820 MultisampleState ,
1921 RasterizerState ,
2022 ResourceDescription ,
2123 ResourceId ,
2224 ShaderReflection ,
2325 ShaderStage ,
26+ ShaderValue ,
27+ ShaderVariable ,
2428)
2529
2630from rdc .adapter import RenderDocAdapter
@@ -46,6 +50,20 @@ def _req(method: str, **params: Any) -> dict[str, Any]:
4650def _make_state (tmp_path : Path , pipe : MockPipeState ) -> DaemonState :
4751 actions = _build_actions ()
4852 resources = _build_resources ()
53+ cbvars : dict [tuple [int , int ], list [Any ]] = {}
54+
55+ def _get_cbuf (
56+ _pipe : Any ,
57+ _sh : Any ,
58+ stage : Any ,
59+ _e : str ,
60+ idx : int ,
61+ _r : Any ,
62+ _o : int ,
63+ _s : int ,
64+ ) -> list [Any ]:
65+ return cbvars .get ((int (stage ), idx ), [])
66+
4967 controller = SimpleNamespace (
5068 GetRootActions = lambda : actions ,
5169 GetResources = lambda : resources ,
@@ -57,6 +75,8 @@ def _make_state(tmp_path: Path, pipe: MockPipeState) -> DaemonState:
5775 GetBuffers = lambda : [],
5876 GetDebugMessages = lambda : [],
5977 Shutdown = lambda : None ,
78+ _cbuffer_variables = cbvars ,
79+ GetCBufferVariableContents = _get_cbuf ,
6080 )
6181 s = DaemonState (capture = "test.rdc" , current_eid = 0 , token = "abcdef1234567890" )
6282 s .adapter = RenderDocAdapter (controller = controller , version = (1 , 41 ))
@@ -144,57 +164,91 @@ def test_empty_when_no_shaders(self, tmp_path: Path) -> None:
144164 resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
145165 assert "error" not in resp
146166 assert resp ["result" ]["push_constants" ] == []
147- assert resp ["result" ]["eid " ] == 10
167+ assert resp ["result" ]["raw_bytes " ] == ""
148168
149- def test_empty_when_size_is_zero (self , tmp_path : Path ) -> None :
169+ def test_empty_when_all_buffer_backed (self , tmp_path : Path ) -> None :
150170 pipe = MockPipeState ()
151171 refl = ShaderReflection (
152172 resourceId = ResourceId (5 ),
153- pushConstantRangeByteOffset = 0 ,
154- pushConstantRangeByteSize = 0 ,
173+ constantBlocks = [ConstantBlock (name = "ubo" , bufferBacked = True , byteSize = 64 )],
155174 )
156175 pipe ._shaders [ShaderStage .Vertex ] = ResourceId (5 )
157176 pipe ._reflections [ShaderStage .Vertex ] = refl
158177 s = _make_state (tmp_path , pipe )
159178 resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
160179 assert resp ["result" ]["push_constants" ] == []
161180
162- def test_returns_range_when_size_nonzero (self , tmp_path : Path ) -> None :
181+ def test_single_stage_push_constants (self , tmp_path : Path ) -> None :
163182 pipe = MockPipeState ()
164- refl = ShaderReflection (
165- resourceId = ResourceId (5 ),
166- pushConstantRangeByteOffset = 16 ,
167- pushConstantRangeByteSize = 64 ,
168- )
183+ cb = ConstantBlock (name = "push_block" , bufferBacked = False , byteSize = 16 )
184+ refl = ShaderReflection (resourceId = ResourceId (5 ), constantBlocks = [cb ])
169185 pipe ._shaders [ShaderStage .Vertex ] = ResourceId (5 )
170186 pipe ._reflections [ShaderStage .Vertex ] = refl
187+ pipe ._cbuffer_descriptors [(ShaderStage .Vertex , 0 )] = Descriptor (
188+ resource = ResourceId (100 ),
189+ byteSize = 16 ,
190+ )
191+ val = ShaderValue ()
192+ val .f32v = [1.0 , 2.0 , 3.0 , 4.0 ] + [0.0 ] * 12
193+ var = ShaderVariable (name = "color" , type = "vec4" , rows = 1 , columns = 4 , value = val )
171194 s = _make_state (tmp_path , pipe )
195+ s .adapter .controller ._cbuffer_variables [(ShaderStage .Vertex , 0 )] = [var ]
172196 resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
173- ranges = resp ["result" ]["push_constants" ]
174- assert len (ranges ) == 1
175- assert ranges [0 ]["stage" ] == "vs"
176- assert ranges [0 ]["offset" ] == 16
177- assert ranges [0 ]["size" ] == 64
197+ result = resp ["result" ]
198+ assert len (result ["push_constants" ]) == 1
199+ pc = result ["push_constants" ][0 ]
200+ assert pc ["stage" ] == "vs"
201+ assert pc ["name" ] == "push_block"
202+ assert pc ["size" ] == 16
203+ assert len (pc ["variables" ]) == 1
204+ assert pc ["variables" ][0 ]["name" ] == "color"
205+ assert pc ["variables" ][0 ]["value" ] == [1.0 , 2.0 , 3.0 , 4.0 ]
178206
179207 def test_multiple_stages (self , tmp_path : Path ) -> None :
180208 pipe = MockPipeState ()
181- for stage , stage_id in (
182- (ShaderStage .Vertex , 5 ),
183- (ShaderStage .Pixel , 6 ),
184- ):
185- refl = ShaderReflection (
186- resourceId = ResourceId (stage_id ),
187- pushConstantRangeByteOffset = 0 ,
188- pushConstantRangeByteSize = 128 ,
189- )
190- pipe ._shaders [stage ] = ResourceId (stage_id )
209+ for stage , sid in ((ShaderStage .Vertex , 5 ), (ShaderStage .Pixel , 6 )):
210+ cb = ConstantBlock (name = "pc" , bufferBacked = False , byteSize = 8 )
211+ refl = ShaderReflection (resourceId = ResourceId (sid ), constantBlocks = [cb ])
212+ pipe ._shaders [stage ] = ResourceId (sid )
191213 pipe ._reflections [stage ] = refl
192214 s = _make_state (tmp_path , pipe )
193215 resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
194- ranges = resp ["result" ]["push_constants" ]
195- stage_names = {r ["stage" ] for r in ranges }
196- assert "vs" in stage_names
197- assert "ps" in stage_names
216+ stages = {pc ["stage" ] for pc in resp ["result" ]["push_constants" ]}
217+ assert "vs" in stages
218+ assert "ps" in stages
219+
220+ def test_raw_bytes_present (self , tmp_path : Path ) -> None :
221+ pipe = MockPipeState ()
222+ pipe .pushconsts = b"\x01 \x02 \xab "
223+ s = _make_state (tmp_path , pipe )
224+ resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
225+ assert resp ["result" ]["raw_bytes" ] == "0102ab"
226+
227+ def test_raw_bytes_empty_when_no_attr (self , tmp_path : Path ) -> None :
228+ pipe = MockPipeState ()
229+ delattr (pipe , "pushconsts" )
230+ s = _make_state (tmp_path , pipe )
231+ resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
232+ assert resp ["result" ]["raw_bytes" ] == ""
233+
234+ def test_mixed_buffer_backed_and_push (self , tmp_path : Path ) -> None :
235+ pipe = MockPipeState ()
236+ blocks = [
237+ ConstantBlock (name = "ubo" , bufferBacked = True , byteSize = 64 ),
238+ ConstantBlock (name = "pc" , bufferBacked = False , byteSize = 16 ),
239+ ]
240+ refl = ShaderReflection (resourceId = ResourceId (5 ), constantBlocks = blocks )
241+ pipe ._shaders [ShaderStage .Vertex ] = ResourceId (5 )
242+ pipe ._reflections [ShaderStage .Vertex ] = refl
243+ pipe ._cbuffer_descriptors [(ShaderStage .Vertex , 1 )] = Descriptor (
244+ resource = ResourceId (200 ),
245+ byteSize = 16 ,
246+ )
247+ s = _make_state (tmp_path , pipe )
248+ resp , _ = _handle_request (_req ("pipe_push_constants" , eid = 10 ), s )
249+ pcs = resp ["result" ]["push_constants" ]
250+ assert len (pcs ) == 1
251+ assert pcs [0 ]["name" ] == "pc"
198252
199253
200254# ── pipe_rasterizer ───────────────────────────────────────────────────────────
0 commit comments