@@ -2308,15 +2308,14 @@ void GSDevice12::OMSetRenderTargets(GSTexture* rt, GSTexture* ds_as_rt, GSTextur
23082308
23092309 // Unbind conflicting UAVs
23102310 std::array<GSTexture12*, 3 > curr_rts{ m_current_render_target, m_current_depth_render_target, m_current_depth_target };
2311- std::array<GSTexture12**, 2 > curr_uavs{ &m_tfx_uavs_tex [0 ], &m_tfx_uavs_tex [1 ] };
2312- for (GSTexture12** uav : curr_uavs )
2311+ std::array<GSTexture12**, 2 > curr_uavs{ &m_tfx_textures_uav [0 ], &m_tfx_textures_uav [1 ] };
2312+ for (u32 i = TEXTURE_RT_UAV; i <= TEXTURE_DEPTH_UAV; i++ )
23132313 {
23142314 for (GSTexture12* rt : curr_rts)
23152315 {
2316- if (*uav == rt)
2316+ if (m_tfx_textures_uav[i - TEXTURE_RT_UAV] == rt)
23172317 {
2318- *uav = nullptr ;
2319- m_dirty_flags |= DIRTY_FLAG_TFX_UAV_TEXTURES;
2318+ PSSetUnorderedAccess (i, nullptr , false );
23202319 }
23212320 }
23222321 }
@@ -2509,11 +2508,15 @@ bool GSDevice12::CreateRootSignatures()
25092508 rsb.AddCBVParameter (0 , D3D12_SHADER_VISIBILITY_ALL);
25102509 rsb.AddCBVParameter (1 , D3D12_SHADER_VISIBILITY_PIXEL);
25112510 rsb.AddSRVParameter (0 , D3D12_SHADER_VISIBILITY_VERTEX);
2512- rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0 , 2 , D3D12_SHADER_VISIBILITY_PIXEL); // Source / Palette
2511+ rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0 , 2 , D3D12_SHADER_VISIBILITY_PIXEL); // Source (t0) / Palette (t2)
25132512 rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0 , NUM_TFX_SAMPLERS, D3D12_SHADER_VISIBILITY_PIXEL);
2514- rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2 , 2 , D3D12_SHADER_VISIBILITY_PIXEL); // RT / PrimID
2515- rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 4 , 1 , D3D12_SHADER_VISIBILITY_PIXEL); // Depth
2516- rsb.AddDescriptorTable (D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0 , 2 , D3D12_SHADER_VISIBILITY_PIXEL);
2513+
2514+ // RT (t2) / PrimID (t3) / Depth (t4) / RT UAV (u0) / Depth UAV (u1)
2515+ D3D12_DESCRIPTOR_RANGE_TYPE rt_types[2 ] = { D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_DESCRIPTOR_RANGE_TYPE_UAV };
2516+ u32 rt_start_regs[2 ] = { 2 , 0 };
2517+ u32 rt_num_regs[2 ] = { 3 , 2 };
2518+ rsb.AddDescriptorTableMultiRange (2 , rt_types, rt_start_regs, rt_num_regs, D3D12_SHADER_VISIBILITY_PIXEL);
2519+
25172520 if (!(m_tfx_root_signature = rsb.Create ()))
25182521 return false ;
25192522 D3D12::SetObjectName (m_tfx_root_signature.get (), " TFX root signature" );
@@ -3186,10 +3189,10 @@ bool GSDevice12::BindDrawPipeline(const PipelineSelector& p)
31863189
31873190void GSDevice12::InitializeState ()
31883191{
3189- for (u32 i = 0 ; i < NUM_TOTAL_TFX_TEXTURES ; i++)
3192+ for (u32 i = 0 ; i < TEXTURE_RT_UAV ; i++)
31903193 m_tfx_textures[i] = m_null_texture->GetSRVDescriptor ();
3191- for (u32 i = 0 ; i < NUM_TFX_UAV_TEXTURES ; i++)
3192- m_tfx_uavs [i] = m_null_texture->GetUAVDescriptor ();
3194+ for (u32 i = TEXTURE_RT_UAV ; i < NUM_TOTAL_TFX_TEXTURES ; i++)
3195+ m_tfx_textures [i] = m_null_texture->GetUAVDescriptor ();
31933196 m_tfx_sampler_sel = GSHWDrawConfig::SamplerSelector::Point ().key ;
31943197
31953198 InvalidateCachedState ();
@@ -3277,8 +3280,6 @@ void GSDevice12::InvalidateCachedState()
32773280 m_tfx_textures_handle_gpu.Clear ();
32783281 m_tfx_samplers_handle_gpu.Clear ();
32793282 m_tfx_rt_textures_handle_gpu.Clear ();
3280- m_tfx_depth_textures_handle_gpu.Clear ();
3281- m_tfx_uav_textures_handle_gpu.Clear ();
32823283}
32833284
32843285void GSDevice12::SetVertexBuffer (D3D12_GPU_VIRTUAL_ADDRESS buffer, size_t size, size_t stride)
@@ -3333,6 +3334,8 @@ void GSDevice12::SetStencilRef(u8 ref)
33333334
33343335void GSDevice12::PSSetShaderResource (int i, GSTexture* sr, bool check_state, bool feedback)
33353336{
3337+ pxAssertRel (i < NUM_TFX_TEXTURES + NUM_TFX_RT_TEXTURES, " Trying to bind UAV slot with wrong function" );
3338+
33363339 D3D12DescriptorHandle handle;
33373340 if (sr)
33383341 {
@@ -3366,11 +3369,7 @@ void GSDevice12::PSSetShaderResource(int i, GSTexture* sr, bool check_state, boo
33663369 return ;
33673370
33683371 m_tfx_textures[i] = handle;
3369- m_dirty_flags |=
3370- (i < 2 ) ? DIRTY_FLAG_TFX_TEXTURES :
3371- (i < 4 ) ? DIRTY_FLAG_TFX_RT_TEXTURES :
3372- (i < 5 ) ? DIRTY_FLAG_TFX_DEPTH_TEXTURES :
3373- 0 ;
3372+ m_dirty_flags |= (i < NUM_TFX_TEXTURES) ? DIRTY_FLAG_TFX_TEXTURES : DIRTY_FLAG_TFX_RT_TEXTURES;
33743373}
33753374
33763375void GSDevice12::PSSetSampler (GSHWDrawConfig::SamplerSelector sel)
@@ -3385,6 +3384,8 @@ void GSDevice12::PSSetSampler(GSHWDrawConfig::SamplerSelector sel)
33853384
33863385void GSDevice12::PSSetUnorderedAccess (int i, GSTexture* uav, bool check_state)
33873386{
3387+ pxAssertRel (TEXTURE_RT_UAV <= i && i <= TEXTURE_DEPTH_UAV, " Trying to bind UAV in wrong slot" );
3388+
33883389 if (InRenderPass ())
33893390 {
33903391 GL_INS (" Ending render pass due to binding UAV." );
@@ -3415,17 +3416,20 @@ void GSDevice12::PSSetUnorderedAccess(int i, GSTexture* uav, bool check_state)
34153416 bind_uav = m_null_texture.get ();
34163417 }
34173418
3418- if (m_tfx_uavs_tex[i] == bind_uav)
3419+ const int i_uav = i - TEXTURE_RT_UAV;
3420+
3421+ if (m_tfx_textures_uav[i_uav] == bind_uav)
34193422 return ;
34203423
3421- m_tfx_uavs_tex[i] = static_cast <GSTexture12*>(bind_uav);
3422- m_tfx_uavs[i] = m_tfx_uavs_tex[i]->GetUAVDescriptor ();
3423- m_dirty_flags |= DIRTY_FLAG_TFX_UAV_TEXTURES;
3424+ // Store pointer to the texture in addition to descriptor since depth UAVs have a color copy.
3425+ m_tfx_textures_uav[i_uav] = static_cast <GSTexture12*>(bind_uav);
3426+ m_tfx_textures[i] = static_cast <GSTexture12*>(bind_uav)->GetUAVDescriptor ();
3427+ m_dirty_flags |= DIRTY_FLAG_TFX_RT_TEXTURES;
34243428
34253429 std::array<GSTexture12**, 3 > curr_rts{ &m_current_render_target, &m_current_depth_render_target, &m_current_depth_target };
34263430 for (GSTexture12** rt : curr_rts)
34273431 {
3428- if (*rt == m_tfx_uavs_tex[i ])
3432+ if (*rt == m_tfx_textures_uav[i_uav ])
34293433 {
34303434 *rt = nullptr ;
34313435 m_dirty_flags |= DIRTY_FLAG_RENDER_TARGET;
@@ -3499,22 +3503,37 @@ void GSDevice12::SetUtilityPushConstants(const void* data, u32 size)
34993503
35003504void GSDevice12::UnbindTexture (GSTexture12* tex)
35013505{
3502- for (u32 i = 0 ; i < NUM_TOTAL_TFX_TEXTURES; i++)
3506+ // Source / palette
3507+ for (u32 i = 0 ; i <= TEXTURE_PALETTE; i++)
35033508 {
35043509 if (m_tfx_textures[i] == tex->GetSRVDescriptor () || m_tfx_textures[i] == tex->GetFBLDescriptor ())
35053510 {
35063511 m_tfx_textures[i] = m_null_texture->GetSRVDescriptor ();
35073512 m_dirty_flags |= DIRTY_FLAG_TFX_TEXTURES;
35083513 }
35093514 }
3510- for (u32 i = 0 ; i < NUM_TFX_UAV_TEXTURES; i++)
3515+
3516+ // RT / primid / depth
3517+ for (u32 i = TEXTURE_RT; i <= TEXTURE_DEPTH; i++)
3518+ {
3519+ if (m_tfx_textures[i] == tex->GetSRVDescriptor () || m_tfx_textures[i] == tex->GetFBLDescriptor ())
3520+ {
3521+ m_tfx_textures[i] = m_null_texture->GetSRVDescriptor ();
3522+ m_dirty_flags |= DIRTY_FLAG_TFX_RT_TEXTURES;
3523+ }
3524+ }
3525+
3526+ // RT UAV / depth UAV
3527+ for (u32 i = TEXTURE_RT_UAV; i <= TEXTURE_DEPTH_UAV; i++)
35113528 {
3512- if (m_tfx_uavs_tex[i ] == tex)
3529+ if (m_tfx_textures_uav[i - TEXTURE_RT_UAV ] == tex)
35133530 {
3514- m_tfx_uavs_tex[i] = nullptr ;
3531+ m_tfx_textures_uav[i - TEXTURE_RT_UAV] = nullptr ;
3532+ m_tfx_textures[i] = m_null_texture->GetUAVDescriptor ();
3533+ m_dirty_flags |= DIRTY_FLAG_TFX_RT_TEXTURES;
35153534 }
3516- m_dirty_flags |= DIRTY_FLAG_TFX_UAV_TEXTURES;
35173535 }
3536+
35183537 if (m_current_render_target == tex)
35193538 {
35203539 EndRenderPass ();
@@ -3854,7 +3873,7 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
38543873
38553874 if (flags & DIRTY_FLAG_TFX_RT_TEXTURES)
38563875 {
3857- if (!GetTextureGroupDescriptors (&m_tfx_rt_textures_handle_gpu, m_tfx_textures.data () + 2 , 2 ))
3876+ if (!GetTextureGroupDescriptors (&m_tfx_rt_textures_handle_gpu, m_tfx_textures.data () + 2 , 5 ))
38583877 {
38593878 ExecuteCommandListAndRestartRenderPass (false , " Ran out of TFX RT descriptor descriptor groups" );
38603879 return ApplyTFXState (true );
@@ -3863,34 +3882,14 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
38633882 flags |= DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2;
38643883 }
38653884
3866- if (flags & DIRTY_FLAG_TFX_DEPTH_TEXTURES)
3867- {
3868- if (!GetTextureGroupDescriptors (&m_tfx_depth_textures_handle_gpu, m_tfx_textures.data () + 4 , 1 ))
3869- {
3870- ExecuteCommandListAndRestartRenderPass (false , " Ran out of TFX depth descriptor descriptor groups" );
3871- return ApplyTFXState (true );
3872- }
3873- flags |= DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_3;
3874- }
3875- if (flags & DIRTY_FLAG_TFX_UAV_TEXTURES)
3876- {
3877- if (!GetTextureGroupDescriptors (&m_tfx_uav_textures_handle_gpu, m_tfx_uavs.data (), 2 ))
3878- {
3879- ExecuteCommandListAndRestartRenderPass (false , " Ran out of TFX UAV descriptor descriptor groups" );
3880- return ApplyTFXState (true );
3881- }
3882- flags |= DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_4;
3883- }
3884-
38853885 ID3D12GraphicsCommandList* cmdlist = GetCommandList ();
38863886
38873887 if (m_current_root_signature != RootSignature::TFX)
38883888 {
38893889 m_current_root_signature = RootSignature::TFX;
38903890 flags |= DIRTY_FLAG_VS_CONSTANT_BUFFER_BINDING | DIRTY_FLAG_PS_CONSTANT_BUFFER_BINDING |
38913891 DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE |
3892- DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_3 |
3893- DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_4 | DIRTY_FLAG_PIPELINE;
3892+ DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_PIPELINE;
38943893 cmdlist->SetGraphicsRootSignature (m_tfx_root_signature.get ());
38953894 }
38963895
@@ -3909,11 +3908,6 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
39093908 cmdlist->SetGraphicsRootDescriptorTable (TFX_ROOT_SIGNATURE_PARAM_PS_SAMPLERS, m_tfx_samplers_handle_gpu);
39103909 if (flags & DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2)
39113910 cmdlist->SetGraphicsRootDescriptorTable (TFX_ROOT_SIGNATURE_PARAM_PS_RT_TEXTURES, m_tfx_rt_textures_handle_gpu);
3912- if (flags & DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_3)
3913- cmdlist->SetGraphicsRootDescriptorTable (TFX_ROOT_SIGNATURE_PARAM_PS_DEPTH_TEXTURES, m_tfx_depth_textures_handle_gpu);
3914- if (flags & DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_4)
3915- cmdlist->SetGraphicsRootDescriptorTable (TFX_ROOT_SIGNATURE_PARAM_PS_UAV_TEXTURES, m_tfx_uav_textures_handle_gpu);
3916-
39173911
39183912 ApplyBaseState (flags, cmdlist);
39193913 return true ;
@@ -4307,8 +4301,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
43074301 // Clearing/state change is handled in SendHWDraw().
43084302 EndRenderPass ();
43094303
4310- PSSetUnorderedAccess (0 , config.ps .rov_color ? draw_rt : nullptr , true );
4311- PSSetUnorderedAccess (1 , config.ps .rov_depth ? draw_ds : nullptr , true );
4304+ PSSetUnorderedAccess (TEXTURE_RT_UAV , config.ps .rov_color ? draw_rt : nullptr , true );
4305+ PSSetUnorderedAccess (TEXTURE_DEPTH_UAV , config.ps .rov_depth ? draw_ds : nullptr , true );
43124306
43134307 // Warning: PSSetUnorderedAccess may use StretchRect() to update depth UAV so we must
43144308 // call OMSetRenderTargets() after to clear any unused RTs. Otherwise the UAV may end up
@@ -4475,8 +4469,14 @@ void GSDevice12::SendHWDraw(const PipelineSelector& pipe, const GSHWDrawConfig&
44754469 draw_ds->GetState () == GSTexture::State::Cleared ? " Clear" : " ???" ) : " None" ,
44764470 draw_ds ? (config.ps .rov_depth ? " UAV" : " Standard" ) : " None" );
44774471
4478- D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_rt = m_tfx_uav_textures_handle_gpu;
4479- D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_ds = { gpu_handle_rt.ptr + GetDescriptorAllocator ().GetDescriptorIncrementSize () };
4472+ D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_rt = {
4473+ m_tfx_rt_textures_handle_gpu.gpu_handle .ptr +
4474+ (TEXTURE_RT_UAV - TEXTURE_RT) * GetDescriptorAllocator ().GetDescriptorIncrementSize ()
4475+ };
4476+ D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_ds = {
4477+ m_tfx_rt_textures_handle_gpu.gpu_handle .ptr +
4478+ (TEXTURE_DEPTH_UAV - TEXTURE_RT) * GetDescriptorAllocator ().GetDescriptorIncrementSize ()
4479+ };
44804480
44814481 // Do state updates here as we need the GPU descriptor handles to be allocated in
44824482 // BindDrawPipeline() for UAV clears.
0 commit comments