[D3D12] Fix state of textures bound to both VS and PS
This commit is contained in:
parent
fdd97fc831
commit
8341a48210
|
@ -1409,8 +1409,8 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
|
|
||||||
// Update the textures - this may bind pipelines.
|
// Update the textures - this may bind pipelines.
|
||||||
texture_cache_->RequestTextures(
|
texture_cache_->RequestTextures(
|
||||||
vertex_shader->GetUsedTextureMask(),
|
vertex_shader->GetUsedTextureMask() |
|
||||||
pixel_shader != nullptr ? pixel_shader->GetUsedTextureMask() : 0);
|
(pixel_shader != nullptr ? pixel_shader->GetUsedTextureMask() : 0));
|
||||||
|
|
||||||
// Check if early depth/stencil can be enabled.
|
// Check if early depth/stencil can be enabled.
|
||||||
bool early_z;
|
bool early_z;
|
||||||
|
|
|
@ -1250,8 +1250,7 @@ void TextureCache::EndFrame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::RequestTextures(uint32_t used_vertex_texture_mask,
|
void TextureCache::RequestTextures(uint32_t used_texture_mask) {
|
||||||
uint32_t used_pixel_texture_mask) {
|
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
|
|
||||||
#if FINE_GRAINED_DRAW_SCOPES
|
#if FINE_GRAINED_DRAW_SCOPES
|
||||||
|
@ -1268,12 +1267,11 @@ void TextureCache::RequestTextures(uint32_t used_vertex_texture_mask,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the texture keys and the textures.
|
// Update the texture keys and the textures.
|
||||||
uint32_t used_texture_mask =
|
uint32_t textures_remaining = used_texture_mask;
|
||||||
used_vertex_texture_mask | used_pixel_texture_mask;
|
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
while (xe::bit_scan_forward(used_texture_mask, &index)) {
|
while (xe::bit_scan_forward(textures_remaining, &index)) {
|
||||||
uint32_t index_bit = 1u << index;
|
uint32_t index_bit = uint32_t(1) << index;
|
||||||
used_texture_mask &= ~index_bit;
|
textures_remaining &= ~index_bit;
|
||||||
if (texture_keys_in_sync_ & index_bit) {
|
if (texture_keys_in_sync_ & index_bit) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1337,34 +1335,35 @@ void TextureCache::RequestTextures(uint32_t used_vertex_texture_mask,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition the textures to the needed usage.
|
// Transition the textures to the needed usage - always in
|
||||||
used_texture_mask = used_vertex_texture_mask | used_pixel_texture_mask;
|
// NON_PIXEL_SHADER_RESOURCE | PIXEL_SHADER_RESOURCE states because barriers
|
||||||
while (xe::bit_scan_forward(used_texture_mask, &index)) {
|
// between read-only stages, if needed, are discouraged (also if these were
|
||||||
uint32_t index_bit = 1u << index;
|
// tracked separately, checks would be needed to make sure, if the same
|
||||||
used_texture_mask &= ~index_bit;
|
// texture is bound through different fetch constants to both VS and PS, it
|
||||||
|
// would be in both states).
|
||||||
D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATES(0);
|
textures_remaining = used_texture_mask;
|
||||||
if (used_vertex_texture_mask & index_bit) {
|
while (xe::bit_scan_forward(textures_remaining, &index)) {
|
||||||
state |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
|
textures_remaining &= ~(uint32_t(1) << index);
|
||||||
}
|
|
||||||
if (used_pixel_texture_mask & index_bit) {
|
|
||||||
state |= D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureBinding& binding = texture_bindings_[index];
|
TextureBinding& binding = texture_bindings_[index];
|
||||||
if (binding.texture != nullptr) {
|
if (binding.texture != nullptr) {
|
||||||
// Will be referenced by the command list, so mark as used.
|
// Will be referenced by the command list, so mark as used.
|
||||||
MarkTextureUsed(binding.texture);
|
MarkTextureUsed(binding.texture);
|
||||||
command_processor_->PushTransitionBarrier(binding.texture->resource,
|
command_processor_->PushTransitionBarrier(
|
||||||
binding.texture->state, state);
|
binding.texture->resource, binding.texture->state,
|
||||||
binding.texture->state = state;
|
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
|
||||||
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||||
|
binding.texture->state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
|
||||||
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
}
|
}
|
||||||
if (binding.texture_signed != nullptr) {
|
if (binding.texture_signed != nullptr) {
|
||||||
MarkTextureUsed(binding.texture_signed);
|
MarkTextureUsed(binding.texture_signed);
|
||||||
command_processor_->PushTransitionBarrier(
|
command_processor_->PushTransitionBarrier(
|
||||||
binding.texture_signed->resource, binding.texture_signed->state,
|
binding.texture_signed->resource, binding.texture_signed->state,
|
||||||
state);
|
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
|
||||||
binding.texture_signed->state = state;
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||||
|
binding.texture_signed->state =
|
||||||
|
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
|
||||||
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2028,6 +2027,9 @@ bool TextureCache::RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MarkTextureUsed(texture);
|
MarkTextureUsed(texture);
|
||||||
|
// The swap texture is likely to be used only for the presentation pixel
|
||||||
|
// shader, and not during emulation, where it'd be NON_PIXEL_SHADER_RESOURCE |
|
||||||
|
// PIXEL_SHADER_RESOURCE.
|
||||||
command_processor_->PushTransitionBarrier(
|
command_processor_->PushTransitionBarrier(
|
||||||
texture->resource, texture->state,
|
texture->resource, texture->state,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||||
|
|
|
@ -109,8 +109,7 @@ class TextureCache {
|
||||||
// shaders and puts them in the SRV state. This may bind compute pipelines
|
// shaders and puts them in the SRV state. This may bind compute pipelines
|
||||||
// (notifying the command processor about that), so this must be called before
|
// (notifying the command processor about that), so this must be called before
|
||||||
// binding the actual drawing pipeline.
|
// binding the actual drawing pipeline.
|
||||||
void RequestTextures(uint32_t used_vertex_texture_mask,
|
void RequestTextures(uint32_t used_texture_mask);
|
||||||
uint32_t used_pixel_texture_mask);
|
|
||||||
|
|
||||||
// Returns the hash of the current bindings (must be called after
|
// Returns the hash of the current bindings (must be called after
|
||||||
// RequestTextures) for the provided SRV descriptor layout.
|
// RequestTextures) for the provided SRV descriptor layout.
|
||||||
|
@ -160,6 +159,7 @@ class TextureCache {
|
||||||
uint32_t first_unscaled_4kb_page,
|
uint32_t first_unscaled_4kb_page,
|
||||||
uint32_t unscaled_4kb_page_count);
|
uint32_t unscaled_4kb_page_count);
|
||||||
|
|
||||||
|
// Returns a descriptor of the front buffer in PIXEL_SHADER_RESOURCE state.
|
||||||
bool RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
|
bool RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
|
||||||
TextureFormat& format_out);
|
TextureFormat& format_out);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue