[GPU] Non-ROV f24 trunc/round, host shader modifications, cache dir
This commit is contained in:
@@ -73,10 +73,9 @@ void D3D12CommandProcessor::ClearCaches() {
|
||||
}
|
||||
|
||||
void D3D12CommandProcessor::InitializeShaderStorage(
|
||||
const std::filesystem::path& storage_root, uint32_t title_id,
|
||||
bool blocking) {
|
||||
CommandProcessor::InitializeShaderStorage(storage_root, title_id, blocking);
|
||||
pipeline_cache_->InitializeShaderStorage(storage_root, title_id, blocking);
|
||||
const std::filesystem::path& cache_root, uint32_t title_id, bool blocking) {
|
||||
CommandProcessor::InitializeShaderStorage(cache_root, title_id, blocking);
|
||||
pipeline_cache_->InitializeShaderStorage(cache_root, title_id, blocking);
|
||||
}
|
||||
|
||||
void D3D12CommandProcessor::RequestFrameTrace(
|
||||
@@ -102,7 +101,7 @@ void D3D12CommandProcessor::RestoreEdramSnapshot(const void* snapshot) {
|
||||
}
|
||||
|
||||
uint32_t D3D12CommandProcessor::GetCurrentColorMask(
|
||||
const D3D12Shader* pixel_shader) const {
|
||||
const Shader* pixel_shader) const {
|
||||
if (pixel_shader == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -159,25 +158,16 @@ void D3D12CommandProcessor::SubmitBarriers() {
|
||||
}
|
||||
|
||||
ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature(
|
||||
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader) {
|
||||
assert_true(vertex_shader->is_translated());
|
||||
|
||||
const DxbcShader* vertex_shader, const DxbcShader* pixel_shader,
|
||||
bool tessellated) {
|
||||
if (bindless_resources_used_) {
|
||||
return vertex_shader->host_vertex_shader_type() !=
|
||||
Shader::HostVertexShaderType::kVertex
|
||||
? root_signature_bindless_ds_
|
||||
: root_signature_bindless_vs_;
|
||||
return tessellated ? root_signature_bindless_ds_
|
||||
: root_signature_bindless_vs_;
|
||||
}
|
||||
|
||||
assert_true(pixel_shader == nullptr || pixel_shader->is_translated());
|
||||
|
||||
D3D12_SHADER_VISIBILITY vertex_visibility;
|
||||
if (vertex_shader->host_vertex_shader_type() !=
|
||||
Shader::HostVertexShaderType::kVertex) {
|
||||
vertex_visibility = D3D12_SHADER_VISIBILITY_DOMAIN;
|
||||
} else {
|
||||
vertex_visibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
||||
}
|
||||
D3D12_SHADER_VISIBILITY vertex_visibility =
|
||||
tessellated ? D3D12_SHADER_VISIBILITY_DOMAIN
|
||||
: D3D12_SHADER_VISIBILITY_VERTEX;
|
||||
|
||||
uint32_t texture_count_vertex, sampler_count_vertex;
|
||||
vertex_shader->GetTextureBindings(texture_count_vertex);
|
||||
@@ -393,7 +383,7 @@ ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature(
|
||||
}
|
||||
|
||||
uint32_t D3D12CommandProcessor::GetRootBindfulExtraParameterIndices(
|
||||
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader,
|
||||
const DxbcShader* vertex_shader, const DxbcShader* pixel_shader,
|
||||
RootBindfulExtraParameterIndices& indices_out) {
|
||||
uint32_t texture_count_pixel = 0, sampler_count_pixel = 0;
|
||||
if (pixel_shader != nullptr) {
|
||||
@@ -1202,6 +1192,7 @@ bool D3D12CommandProcessor::SetupContext() {
|
||||
|
||||
pipeline_cache_ = std::make_unique<PipelineCache>(
|
||||
*this, *register_file_, bindless_resources_used_, edram_rov_used_,
|
||||
render_target_cache_->depth_float24_conversion(),
|
||||
texture_cache_->IsResolutionScale2X() ? 2 : 1);
|
||||
if (!pipeline_cache_->Initialize()) {
|
||||
XELOGE("Failed to initialize the graphics pipeline cache");
|
||||
@@ -1804,8 +1795,7 @@ Shader* D3D12CommandProcessor::LoadShader(xenos::ShaderType shader_type,
|
||||
uint32_t guest_address,
|
||||
const uint32_t* host_address,
|
||||
uint32_t dword_count) {
|
||||
return pipeline_cache_->LoadShader(shader_type, guest_address, host_address,
|
||||
dword_count);
|
||||
return pipeline_cache_->LoadShader(shader_type, host_address, dword_count);
|
||||
}
|
||||
|
||||
bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
@@ -1851,21 +1841,30 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
// Need a pixel shader in normal color mode.
|
||||
return false;
|
||||
}
|
||||
// Get tessellation info for the current draw for vertex shader translation.
|
||||
Shader::HostVertexShaderType host_vertex_shader_type =
|
||||
pipeline_cache_->GetHostVertexShaderTypeIfValid();
|
||||
if (host_vertex_shader_type == Shader::HostVertexShaderType(-1)) {
|
||||
DxbcShaderTranslator::Modification vertex_shader_modification;
|
||||
DxbcShaderTranslator::Modification pixel_shader_modification;
|
||||
if (!pipeline_cache_->GetCurrentShaderModifications(
|
||||
vertex_shader_modification, pixel_shader_modification)) {
|
||||
return false;
|
||||
}
|
||||
D3D12Shader::D3D12Translation* vertex_shader_translation =
|
||||
static_cast<D3D12Shader::D3D12Translation*>(
|
||||
vertex_shader->GetOrCreateTranslation(
|
||||
vertex_shader_modification.value));
|
||||
D3D12Shader::D3D12Translation* pixel_shader_translation =
|
||||
pixel_shader ? static_cast<D3D12Shader::D3D12Translation*>(
|
||||
pixel_shader->GetOrCreateTranslation(
|
||||
pixel_shader_modification.value))
|
||||
: nullptr;
|
||||
// Translate the shaders now to get memexport configuration and color mask,
|
||||
// which is needed by the render target cache, to check the possibility of
|
||||
// doing early depth/stencil, and also to get used textures and samplers.
|
||||
if (!pipeline_cache_->EnsureShadersTranslated(vertex_shader, pixel_shader,
|
||||
host_vertex_shader_type)) {
|
||||
// which is needed by the render target cache, and also to get used textures
|
||||
// and samplers.
|
||||
if (!pipeline_cache_->EnsureShadersTranslated(vertex_shader_translation,
|
||||
pixel_shader_translation)) {
|
||||
return false;
|
||||
}
|
||||
bool tessellated =
|
||||
host_vertex_shader_type != Shader::HostVertexShaderType::kVertex;
|
||||
bool tessellated = vertex_shader_modification.host_vertex_shader_type !=
|
||||
Shader::HostVertexShaderType::kVertex;
|
||||
|
||||
// Check if memexport is used. If it is, we can't skip draw calls that have no
|
||||
// visual effect.
|
||||
@@ -1967,26 +1966,14 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
(pixel_shader != nullptr ? pixel_shader->GetUsedTextureMask() : 0);
|
||||
texture_cache_->RequestTextures(used_texture_mask);
|
||||
|
||||
// Check if early depth/stencil can be enabled.
|
||||
bool early_z;
|
||||
if (pixel_shader) {
|
||||
auto rb_colorcontrol = regs.Get<reg::RB_COLORCONTROL>();
|
||||
early_z = pixel_shader->implicit_early_z_allowed() &&
|
||||
(!rb_colorcontrol.alpha_test_enable ||
|
||||
rb_colorcontrol.alpha_func == xenos::CompareFunction::kAlways) &&
|
||||
!rb_colorcontrol.alpha_to_mask_enable;
|
||||
} else {
|
||||
early_z = true;
|
||||
}
|
||||
|
||||
// Create the pipeline if needed and bind it.
|
||||
void* pipeline_handle;
|
||||
ID3D12RootSignature* root_signature;
|
||||
if (!pipeline_cache_->ConfigurePipeline(
|
||||
vertex_shader, pixel_shader, primitive_type_converted,
|
||||
vertex_shader_translation, pixel_shader_translation,
|
||||
primitive_type_converted,
|
||||
indexed ? index_buffer_info->format : xenos::IndexFormat::kInt16,
|
||||
early_z, pipeline_render_targets, &pipeline_handle,
|
||||
&root_signature)) {
|
||||
pipeline_render_targets, &pipeline_handle, &root_signature)) {
|
||||
return false;
|
||||
}
|
||||
if (current_cached_pipeline_ != pipeline_handle) {
|
||||
@@ -2014,11 +2001,18 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
pixel_size_x *= 2;
|
||||
pixel_size_y *= 2;
|
||||
}
|
||||
flags::DepthFloat24Conversion depth_float24_conversion =
|
||||
render_target_cache_->depth_float24_conversion();
|
||||
draw_util::ViewportInfo viewport_info;
|
||||
draw_util::GetHostViewportInfo(regs, float(pixel_size_x), float(pixel_size_y),
|
||||
true, float(D3D12_VIEWPORT_BOUNDS_MAX),
|
||||
float(D3D12_VIEWPORT_BOUNDS_MAX), false,
|
||||
viewport_info);
|
||||
draw_util::GetHostViewportInfo(
|
||||
regs, float(pixel_size_x), float(pixel_size_y), true,
|
||||
float(D3D12_VIEWPORT_BOUNDS_MAX), float(D3D12_VIEWPORT_BOUNDS_MAX), false,
|
||||
!edram_rov_used_ &&
|
||||
(depth_float24_conversion ==
|
||||
flags::DepthFloat24Conversion::kOnOutputTruncating ||
|
||||
depth_float24_conversion ==
|
||||
flags::DepthFloat24Conversion::kOnOutputRounding),
|
||||
viewport_info);
|
||||
draw_util::Scissor scissor;
|
||||
draw_util::GetScissor(regs, scissor);
|
||||
scissor.left *= pixel_size_x;
|
||||
@@ -2033,7 +2027,7 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
UpdateSystemConstantValues(
|
||||
memexport_used, primitive_polygonal, line_loop_closing_index,
|
||||
indexed ? index_buffer_info->endianness : xenos::Endian::kNone,
|
||||
viewport_info, pixel_size_x, pixel_size_y, used_texture_mask, early_z,
|
||||
viewport_info, pixel_size_x, pixel_size_y, used_texture_mask,
|
||||
GetCurrentColorMask(pixel_shader), pipeline_render_targets);
|
||||
|
||||
// Update constant buffers, descriptors and root parameters.
|
||||
@@ -2873,8 +2867,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||
bool shared_memory_is_uav, bool primitive_polygonal,
|
||||
uint32_t line_loop_closing_index, xenos::Endian index_endian,
|
||||
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
|
||||
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,
|
||||
uint32_t color_mask,
|
||||
uint32_t pixel_size_y, uint32_t used_texture_mask, uint32_t color_mask,
|
||||
const RenderTargetCache::PipelineRenderTarget render_targets[4]) {
|
||||
#if XE_UI_D3D12_FINE_GRAINED_DRAW_SCOPES
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
@@ -2992,14 +2985,11 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||
flags |= DxbcShaderTranslator::kSysFlag_KillIfAnyVertexKilled;
|
||||
}
|
||||
// Alpha test.
|
||||
if (rb_colorcontrol.alpha_test_enable) {
|
||||
flags |= uint32_t(rb_colorcontrol.alpha_func)
|
||||
<< DxbcShaderTranslator::kSysFlag_AlphaPassIfLess_Shift;
|
||||
} else {
|
||||
flags |= DxbcShaderTranslator::kSysFlag_AlphaPassIfLess |
|
||||
DxbcShaderTranslator::kSysFlag_AlphaPassIfEqual |
|
||||
DxbcShaderTranslator::kSysFlag_AlphaPassIfGreater;
|
||||
}
|
||||
xenos::CompareFunction alpha_test_function =
|
||||
rb_colorcontrol.alpha_test_enable ? rb_colorcontrol.alpha_func
|
||||
: xenos::CompareFunction::kAlways;
|
||||
flags |= uint32_t(alpha_test_function)
|
||||
<< DxbcShaderTranslator::kSysFlag_AlphaPassIfLess_Shift;
|
||||
// Gamma writing.
|
||||
for (uint32_t i = 0; i < 4; ++i) {
|
||||
if (color_infos[i].color_format ==
|
||||
@@ -3028,7 +3018,9 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||
if (rb_depthcontrol.stencil_enable) {
|
||||
flags |= DxbcShaderTranslator::kSysFlag_ROVStencilTest;
|
||||
}
|
||||
if (early_z) {
|
||||
// Hint - if not applicable to the shader, will not have effect.
|
||||
if (alpha_test_function == xenos::CompareFunction::kAlways &&
|
||||
!rb_colorcontrol.alpha_to_mask_enable) {
|
||||
flags |= DxbcShaderTranslator::kSysFlag_ROVDepthStencilEarlyWrite;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user