rsx/vulkan: Add post-compilation key validation and dynamically determine attachment write maks based on decompiled shader

- A new step is added between decompilation and pipeline object creation allowing for properties to be updated based on shader contents
- Allos masking off attachment writes that are unmodified in the shader
This commit is contained in:
kd-11 2018-02-23 17:35:44 +03:00
parent 705820c430
commit 87741141f1
6 changed files with 28 additions and 1 deletions

View File

@ -78,6 +78,7 @@ namespace program_hash_util
* - static void recompile_fragment_program(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID);
* - static void recompile_vertex_program(RSXVertexProgram *RSXVP, VertexProgramData& vertexProgramData, size_t ID);
* - static PipelineData build_program(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData);
* - static void validate_pipeline_properties(const VertexProgramData &vertexProgramData, const FragmentProgramData &fragmentProgramData, PipelineProperties& props);
*/
template<typename backend_traits>
class program_state_cache
@ -261,7 +262,7 @@ public:
pipeline_storage_type& getGraphicPipelineState(
const RSXVertexProgram& vertexShader,
const RSXFragmentProgram& fragmentShader,
const pipeline_properties& pipelineProperties,
pipeline_properties& pipelineProperties,
Args&& ...args
)
{
@ -273,6 +274,7 @@ public:
bool already_existing_fragment_program = std::get<1>(fp_search);
bool already_existing_vertex_program = std::get<1>(vp_search);
backend_traits::validate_pipeline_properties(vertex_program, fragment_program, pipelineProperties);
pipeline_key key = { vertex_program.id, fragment_program.id, pipelineProperties };
if (already_existing_fragment_program && already_existing_vertex_program)

View File

@ -145,6 +145,11 @@ struct D3D12Traits
vertexProgramData.id = (u32)ID;
}
static
void validate_pipeline_properties(const vertex_program_type&, const fragment_program_type&, pipeline_properties&)
{
}
static
pipeline_storage_type build_pipeline(
const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData, const pipeline_properties &pipelineProperties,

View File

@ -24,6 +24,11 @@ struct GLTraits
vertexProgramData.Compile();
}
static
void validate_pipeline_properties(const vertex_program_type&, const fragment_program_type&, pipeline_properties&)
{
}
static
pipeline_storage_type build_pipeline(const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData, const pipeline_properties&)
{

View File

@ -96,7 +96,10 @@ void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
{
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", table[i].second))
{
OS << "layout(location=" << std::to_string(output_index++) << ") " << "out vec4 " << table[i].first << ";\n";
vk_prog->output_color_masks[i] = UINT32_MAX;
}
}
}

View File

@ -52,6 +52,8 @@ public:
std::string shader;
std::vector<size_t> FragmentConstantOffsetCache;
std::array<u32, 4> output_color_masks{ {} };
std::vector<vk::glsl::program_input> uniforms;
void SetInputs(std::vector<vk::glsl::program_input>& uniforms);
/**

View File

@ -95,6 +95,16 @@ struct VKTraits
vertexProgramData.Compile();
}
static
void validate_pipeline_properties(const VKVertexProgram&, const VKFragmentProgram &fp, vk::pipeline_props& properties)
{
//Explicitly disable writing to undefined registers
properties.att_state[0].colorWriteMask &= fp.output_color_masks[0];
properties.att_state[1].colorWriteMask &= fp.output_color_masks[1];
properties.att_state[2].colorWriteMask &= fp.output_color_masks[2];
properties.att_state[3].colorWriteMask &= fp.output_color_masks[3];
}
static
pipeline_storage_type build_pipeline(const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData,
const vk::pipeline_props &pipelineProperties, VkDevice dev, VkPipelineLayout common_pipeline_layout)