mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-28 11:35:11 +00:00
[TEST] Geometry shader changes + barrier fixes
This commit is contained in:
@@ -169,11 +169,36 @@ std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings(
|
|||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PassthroughVertices {
|
||||||
|
u32 count;
|
||||||
|
u32 first;
|
||||||
|
u32 stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
PassthroughVertices GetPassthroughVertices(InputTopology input_topology) {
|
||||||
|
switch (input_topology) {
|
||||||
|
case InputTopology::Points:
|
||||||
|
return {1, 0, 1};
|
||||||
|
case InputTopology::Lines:
|
||||||
|
return {2, 0, 1};
|
||||||
|
case InputTopology::LinesAdjacency:
|
||||||
|
return {2, 1, 1};
|
||||||
|
case InputTopology::Triangles:
|
||||||
|
return {3, 0, 1};
|
||||||
|
case InputTopology::TrianglesAdjacency:
|
||||||
|
return {3, 0, 2};
|
||||||
|
}
|
||||||
|
return {3, 0, 1};
|
||||||
|
}
|
||||||
|
|
||||||
void EmitGeometryPassthrough(IR::IREmitter& ir, const IR::Program& program,
|
void EmitGeometryPassthrough(IR::IREmitter& ir, const IR::Program& program,
|
||||||
const Shader::VaryingState& passthrough_mask,
|
const Shader::VaryingState& passthrough_mask,
|
||||||
bool passthrough_position,
|
bool passthrough_position,
|
||||||
std::optional<IR::Attribute> passthrough_layer_attr) {
|
std::optional<IR::Attribute> passthrough_layer_attr,
|
||||||
for (u32 i = 0; i < program.output_vertices; i++) {
|
InputTopology input_topology) {
|
||||||
|
const PassthroughVertices vertices{GetPassthroughVertices(input_topology)};
|
||||||
|
for (u32 vertex = 0; vertex < vertices.count; vertex++) {
|
||||||
|
const u32 i = vertices.first + vertex * vertices.stride;
|
||||||
// Assign generics from input
|
// Assign generics from input
|
||||||
for (u32 j = 0; j < 32; j++) {
|
for (u32 j = 0; j < 32; j++) {
|
||||||
if (!passthrough_mask.Generic(j)) {
|
if (!passthrough_mask.Generic(j)) {
|
||||||
@@ -208,25 +233,16 @@ void EmitGeometryPassthrough(IR::IREmitter& ir, const IR::Program& program,
|
|||||||
ir.EndPrimitive(ir.Imm32(0));
|
ir.EndPrimitive(ir.Imm32(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetOutputTopologyVertices(OutputTopology output_topology) {
|
void LowerGeometryPassthrough(const IR::Program& program, const HostTranslateInfo& host_info,
|
||||||
switch (output_topology) {
|
InputTopology input_topology) {
|
||||||
case OutputTopology::PointList:
|
|
||||||
return 1;
|
|
||||||
case OutputTopology::LineStrip:
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LowerGeometryPassthrough(const IR::Program& program, const HostTranslateInfo& host_info) {
|
|
||||||
for (IR::Block* const block : program.blocks) {
|
for (IR::Block* const block : program.blocks) {
|
||||||
for (IR::Inst& inst : block->Instructions()) {
|
for (IR::Inst& inst : block->Instructions()) {
|
||||||
if (inst.GetOpcode() == IR::Opcode::Epilogue) {
|
if (inst.GetOpcode() == IR::Opcode::Epilogue) {
|
||||||
IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)};
|
IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||||
EmitGeometryPassthrough(
|
EmitGeometryPassthrough(
|
||||||
ir, program, program.info.passthrough,
|
ir, program, program.info.passthrough,
|
||||||
program.info.passthrough.AnyComponent(IR::Attribute::PositionX), {});
|
program.info.passthrough.AnyComponent(IR::Attribute::PositionX), {},
|
||||||
|
input_topology);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +251,8 @@ void LowerGeometryPassthrough(const IR::Program& program, const HostTranslateInf
|
|||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool,
|
IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool,
|
||||||
Environment& env, Flow::CFG& cfg, const HostTranslateInfo& host_info) {
|
Environment& env, Flow::CFG& cfg, const HostTranslateInfo& host_info,
|
||||||
|
InputTopology input_topology) {
|
||||||
HostTranslateInfo normalized_host_info{host_info};
|
HostTranslateInfo normalized_host_info{host_info};
|
||||||
normalized_host_info.ApplyDescriptorLimitPolicy();
|
normalized_host_info.ApplyDescriptorLimitPolicy();
|
||||||
|
|
||||||
@@ -264,8 +281,9 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!normalized_host_info.support_geometry_shader_passthrough) {
|
if (!normalized_host_info.support_geometry_shader_passthrough) {
|
||||||
program.output_vertices = GetOutputTopologyVertices(program.output_topology);
|
program.output_vertices = GetPassthroughVertices(input_topology).count;
|
||||||
LowerGeometryPassthrough(program, normalized_host_info);
|
LowerGeometryPassthrough(program, normalized_host_info, input_topology);
|
||||||
|
program.is_geometry_passthrough = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -414,11 +432,12 @@ IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool,
|
|||||||
ObjectPool<IR::Block>& block_pool,
|
ObjectPool<IR::Block>& block_pool,
|
||||||
const HostTranslateInfo& host_info,
|
const HostTranslateInfo& host_info,
|
||||||
IR::Program& source_program,
|
IR::Program& source_program,
|
||||||
Shader::OutputTopology output_topology) {
|
Shader::OutputTopology output_topology,
|
||||||
|
InputTopology input_topology) {
|
||||||
IR::Program program;
|
IR::Program program;
|
||||||
program.stage = Stage::Geometry;
|
program.stage = Stage::Geometry;
|
||||||
program.output_topology = output_topology;
|
program.output_topology = output_topology;
|
||||||
program.output_vertices = GetOutputTopologyVertices(output_topology);
|
program.output_vertices = GetPassthroughVertices(input_topology).count;
|
||||||
|
|
||||||
program.is_geometry_passthrough = false;
|
program.is_geometry_passthrough = false;
|
||||||
program.info.loads.mask = source_program.info.stores.mask;
|
program.info.loads.mask = source_program.info.stores.mask;
|
||||||
@@ -433,7 +452,7 @@ IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool,
|
|||||||
|
|
||||||
IR::IREmitter ir{*current_block};
|
IR::IREmitter ir{*current_block};
|
||||||
EmitGeometryPassthrough(ir, program, program.info.stores, true,
|
EmitGeometryPassthrough(ir, program, program.info.stores, true,
|
||||||
source_program.info.emulated_layer);
|
source_program.info.emulated_layer, input_topology);
|
||||||
|
|
||||||
IR::Block* return_block{block_pool.Create(inst_pool)};
|
IR::Block* return_block{block_pool.Create(inst_pool)};
|
||||||
IR::IREmitter{*return_block}.Epilogue();
|
IR::IREmitter{*return_block}.Epilogue();
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ namespace Shader::Maxwell {
|
|||||||
|
|
||||||
[[nodiscard]] IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool,
|
[[nodiscard]] IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool,
|
||||||
ObjectPool<IR::Block>& block_pool, Environment& env,
|
ObjectPool<IR::Block>& block_pool, Environment& env,
|
||||||
Flow::CFG& cfg, const HostTranslateInfo& host_info);
|
Flow::CFG& cfg, const HostTranslateInfo& host_info,
|
||||||
|
InputTopology input_topology);
|
||||||
|
|
||||||
[[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b,
|
[[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b,
|
||||||
Environment& env_vertex_b);
|
Environment& env_vertex_b);
|
||||||
@@ -32,6 +33,7 @@ void ConvertLegacyToGeneric(IR::Program& program, const RuntimeInfo& runtime_inf
|
|||||||
ObjectPool<IR::Block>& block_pool,
|
ObjectPool<IR::Block>& block_pool,
|
||||||
const HostTranslateInfo& host_info,
|
const HostTranslateInfo& host_info,
|
||||||
IR::Program& source_program,
|
IR::Program& source_program,
|
||||||
Shader::OutputTopology output_topology);
|
Shader::OutputTopology output_topology,
|
||||||
|
InputTopology input_topology);
|
||||||
|
|
||||||
} // namespace Shader::Maxwell
|
} // namespace Shader::Maxwell
|
||||||
|
|||||||
@@ -72,6 +72,25 @@ Shader::OutputTopology MaxwellToOutputTopology(Maxwell::PrimitiveTopology topolo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::InputTopology MaxwellToInputTopology(Maxwell::PrimitiveTopology topology) {
|
||||||
|
switch (topology) {
|
||||||
|
case Maxwell::PrimitiveTopology::Points:
|
||||||
|
return Shader::InputTopology::Points;
|
||||||
|
case Maxwell::PrimitiveTopology::Lines:
|
||||||
|
case Maxwell::PrimitiveTopology::LineLoop:
|
||||||
|
case Maxwell::PrimitiveTopology::LineStrip:
|
||||||
|
return Shader::InputTopology::Lines;
|
||||||
|
case Maxwell::PrimitiveTopology::LinesAdjacency:
|
||||||
|
case Maxwell::PrimitiveTopology::LineStripAdjacency:
|
||||||
|
return Shader::InputTopology::LinesAdjacency;
|
||||||
|
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
|
||||||
|
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
|
||||||
|
return Shader::InputTopology::TrianglesAdjacency;
|
||||||
|
default:
|
||||||
|
return Shader::InputTopology::Triangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
||||||
const Shader::IR::Program& program,
|
const Shader::IR::Program& program,
|
||||||
const Shader::IR::Program* previous_program,
|
const Shader::IR::Program* previous_program,
|
||||||
@@ -127,33 +146,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (key.gs_input_topology) {
|
info.input_topology = MaxwellToInputTopology(key.gs_input_topology);
|
||||||
case Maxwell::PrimitiveTopology::Points:
|
|
||||||
info.input_topology = Shader::InputTopology::Points;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::Lines:
|
|
||||||
case Maxwell::PrimitiveTopology::LineLoop:
|
|
||||||
case Maxwell::PrimitiveTopology::LineStrip:
|
|
||||||
info.input_topology = Shader::InputTopology::Lines;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::Triangles:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleStrip:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleFan:
|
|
||||||
case Maxwell::PrimitiveTopology::Quads:
|
|
||||||
case Maxwell::PrimitiveTopology::QuadStrip:
|
|
||||||
case Maxwell::PrimitiveTopology::Polygon:
|
|
||||||
case Maxwell::PrimitiveTopology::Patches:
|
|
||||||
info.input_topology = Shader::InputTopology::Triangles;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::LinesAdjacency:
|
|
||||||
case Maxwell::PrimitiveTopology::LineStripAdjacency:
|
|
||||||
info.input_topology = Shader::InputTopology::LinesAdjacency;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
|
|
||||||
info.input_topology = Shader::InputTopology::TrianglesAdjacency;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
info.glasm_use_storage_buffers = glasm_use_storage_buffers;
|
info.glasm_use_storage_buffers = glasm_use_storage_buffers;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -483,8 +476,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
|||||||
&& index == u32(Maxwell::ShaderType::Geometry);
|
&& index == u32(Maxwell::ShaderType::Geometry);
|
||||||
if (key.unique_hashes[index] == 0 && is_emulated_stage) {
|
if (key.unique_hashes[index] == 0 && is_emulated_stage) {
|
||||||
auto topology = MaxwellToOutputTopology(key.gs_input_topology);
|
auto topology = MaxwellToOutputTopology(key.gs_input_topology);
|
||||||
programs[index] = GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
|
programs[index] =
|
||||||
*layer_source_program, topology);
|
GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
|
||||||
|
*layer_source_program, topology,
|
||||||
|
MaxwellToInputTopology(key.gs_input_topology));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (key.unique_hashes[index] == 0) {
|
if (key.unique_hashes[index] == 0) {
|
||||||
@@ -502,13 +497,15 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
|||||||
|
|
||||||
if (!uses_vertex_a || index != 1) {
|
if (!uses_vertex_a || index != 1) {
|
||||||
// Normal path
|
// Normal path
|
||||||
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
MaxwellToInputTopology(key.gs_input_topology));
|
||||||
|
|
||||||
total_storage_buffers += Shader::NumDescriptors(programs[index].info.storage_buffers_descriptors);
|
total_storage_buffers += Shader::NumDescriptors(programs[index].info.storage_buffers_descriptors);
|
||||||
} else {
|
} else {
|
||||||
// VertexB path when VertexA is present.
|
// VertexB path when VertexA is present.
|
||||||
auto& program_va{programs[0]};
|
auto& program_va{programs[0]};
|
||||||
auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
MaxwellToInputTopology(key.gs_input_topology))};
|
||||||
total_storage_buffers += Shader::NumDescriptors(program_vb.info.storage_buffers_descriptors);
|
total_storage_buffers += Shader::NumDescriptors(program_vb.info.storage_buffers_descriptors);
|
||||||
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
|
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
|
||||||
}
|
}
|
||||||
@@ -597,7 +594,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
|||||||
env.Dump(hash, key.unique_hash);
|
env.Dump(hash, key.unique_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
Shader::InputTopology::Points)};
|
||||||
const u32 num_storage_buffers{Shader::NumDescriptors(program.info.storage_buffers_descriptors)};
|
const u32 num_storage_buffers{Shader::NumDescriptors(program.info.storage_buffers_descriptors)};
|
||||||
Shader::RuntimeInfo info;
|
Shader::RuntimeInfo info;
|
||||||
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
|
||||||
|
|||||||
@@ -152,6 +152,25 @@ Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t inde
|
|||||||
return Shader::AttributeType::Disabled;
|
return Shader::AttributeType::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::InputTopology MaxwellToInputTopology(Maxwell::PrimitiveTopology topology) {
|
||||||
|
switch (topology) {
|
||||||
|
case Maxwell::PrimitiveTopology::Points:
|
||||||
|
return Shader::InputTopology::Points;
|
||||||
|
case Maxwell::PrimitiveTopology::Lines:
|
||||||
|
case Maxwell::PrimitiveTopology::LineLoop:
|
||||||
|
case Maxwell::PrimitiveTopology::LineStrip:
|
||||||
|
return Shader::InputTopology::Lines;
|
||||||
|
case Maxwell::PrimitiveTopology::LinesAdjacency:
|
||||||
|
case Maxwell::PrimitiveTopology::LineStripAdjacency:
|
||||||
|
return Shader::InputTopology::LinesAdjacency;
|
||||||
|
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
|
||||||
|
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
|
||||||
|
return Shader::InputTopology::TrianglesAdjacency;
|
||||||
|
default:
|
||||||
|
return Shader::InputTopology::Triangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> programs,
|
Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> programs,
|
||||||
const GraphicsPipelineCacheKey& key,
|
const GraphicsPipelineCacheKey& key,
|
||||||
const Shader::IR::Program& program,
|
const Shader::IR::Program& program,
|
||||||
@@ -270,33 +289,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (key.state.topology) {
|
info.input_topology = MaxwellToInputTopology(key.state.topology);
|
||||||
case Maxwell::PrimitiveTopology::Points:
|
|
||||||
info.input_topology = Shader::InputTopology::Points;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::Lines:
|
|
||||||
case Maxwell::PrimitiveTopology::LineLoop:
|
|
||||||
case Maxwell::PrimitiveTopology::LineStrip:
|
|
||||||
info.input_topology = Shader::InputTopology::Lines;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::Triangles:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleStrip:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleFan:
|
|
||||||
case Maxwell::PrimitiveTopology::Quads:
|
|
||||||
case Maxwell::PrimitiveTopology::QuadStrip:
|
|
||||||
case Maxwell::PrimitiveTopology::Polygon:
|
|
||||||
case Maxwell::PrimitiveTopology::Patches:
|
|
||||||
info.input_topology = Shader::InputTopology::Triangles;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::LinesAdjacency:
|
|
||||||
case Maxwell::PrimitiveTopology::LineStripAdjacency:
|
|
||||||
info.input_topology = Shader::InputTopology::LinesAdjacency;
|
|
||||||
break;
|
|
||||||
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
|
|
||||||
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
|
|
||||||
info.input_topology = Shader::InputTopology::TrianglesAdjacency;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
info.force_early_z = key.state.early_z != 0;
|
info.force_early_z = key.state.early_z != 0;
|
||||||
info.y_negate = key.state.y_negate != 0;
|
info.y_negate = key.state.y_negate != 0;
|
||||||
return info;
|
return info;
|
||||||
@@ -793,8 +786,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||||||
index == static_cast<u32>(Maxwell::ShaderType::Geometry);
|
index == static_cast<u32>(Maxwell::ShaderType::Geometry);
|
||||||
if (key.unique_hashes[index] == 0 && is_emulated_stage) {
|
if (key.unique_hashes[index] == 0 && is_emulated_stage) {
|
||||||
auto topology = MaxwellToOutputTopology(key.state.topology);
|
auto topology = MaxwellToOutputTopology(key.state.topology);
|
||||||
programs[index] = GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
|
programs[index] =
|
||||||
*layer_source_program, topology);
|
GenerateGeometryPassthrough(pools.inst, pools.block, host_info,
|
||||||
|
*layer_source_program, topology,
|
||||||
|
MaxwellToInputTopology(key.state.topology));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (key.unique_hashes[index] == 0) {
|
if (key.unique_hashes[index] == 0) {
|
||||||
@@ -807,11 +802,13 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||||||
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
||||||
if (!uses_vertex_a || index != 1) {
|
if (!uses_vertex_a || index != 1) {
|
||||||
// Normal path
|
// Normal path
|
||||||
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
|
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
MaxwellToInputTopology(key.state.topology));
|
||||||
} else {
|
} else {
|
||||||
// VertexB path when VertexA is present.
|
// VertexB path when VertexA is present.
|
||||||
auto& program_va{programs[0]};
|
auto& program_va{programs[0]};
|
||||||
auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
MaxwellToInputTopology(key.state.topology))};
|
||||||
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
|
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,7 +954,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
|||||||
env.Dump(hash, key.unique_hash);
|
env.Dump(hash, key.unique_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
|
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info,
|
||||||
|
Shader::InputTopology::Points)};
|
||||||
const VkDriverIdKHR driver_id = device.GetDriverID();
|
const VkDriverIdKHR driver_id = device.GetDriverID();
|
||||||
const bool needs_shared_mem_clamp =
|
const bool needs_shared_mem_clamp =
|
||||||
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||||
|
|||||||
@@ -410,8 +410,17 @@ void Scheduler::EndRenderPass()
|
|||||||
Record([num_images = num_renderpass_images,
|
Record([num_images = num_renderpass_images,
|
||||||
images = renderpass_images,
|
images = renderpass_images,
|
||||||
ranges = renderpass_image_ranges,
|
ranges = renderpass_image_ranges,
|
||||||
|
consumer_stages = device.AttachmentConsumerStages(),
|
||||||
has_transform_feedback = device.IsExtTransformFeedbackSupported()](
|
has_transform_feedback = device.IsExtTransformFeedbackSupported()](
|
||||||
vk::CommandBuffer cmdbuf) {
|
vk::CommandBuffer cmdbuf) {
|
||||||
|
static constexpr VkAccessFlags SHADER_ACCESS =
|
||||||
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
|
static constexpr VkAccessFlags COLOR_ACCESS =
|
||||||
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
static constexpr VkAccessFlags DEPTH_STENCIL_ACCESS =
|
||||||
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
std::array<VkImageMemoryBarrier, 9> barriers;
|
std::array<VkImageMemoryBarrier, 9> barriers;
|
||||||
for (size_t i = 0; i < num_images; ++i) {
|
for (size_t i = 0; i < num_images; ++i) {
|
||||||
const VkImageSubresourceRange& range = ranges[i];
|
const VkImageSubresourceRange& range = ranges[i];
|
||||||
@@ -421,24 +430,25 @@ void Scheduler::EndRenderPass()
|
|||||||
| VK_IMAGE_ASPECT_STENCIL_BIT)) !=0;
|
| VK_IMAGE_ASPECT_STENCIL_BIT)) !=0;
|
||||||
|
|
||||||
VkAccessFlags src_access = 0;
|
VkAccessFlags src_access = 0;
|
||||||
|
VkAccessFlags dst_access = SHADER_ACCESS;
|
||||||
|
|
||||||
if (is_color)
|
if (is_color) {
|
||||||
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
else if (is_depth_stencil)
|
dst_access |= COLOR_ACCESS;
|
||||||
|
} else if (is_depth_stencil) {
|
||||||
src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
else
|
dst_access |= DEPTH_STENCIL_ACCESS;
|
||||||
|
} else {
|
||||||
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
dst_access |= COLOR_ACCESS | DEPTH_STENCIL_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
barriers[i] = VkImageMemoryBarrier{
|
barriers[i] = VkImageMemoryBarrier{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.srcAccessMask = src_access,
|
.srcAccessMask = src_access,
|
||||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT
|
.dstAccessMask = dst_access,
|
||||||
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
|
||||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
|
||||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
||||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
||||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
@@ -449,7 +459,7 @@ void Scheduler::EndRenderPass()
|
|||||||
}
|
}
|
||||||
cmdbuf.EndRenderPass();
|
cmdbuf.EndRenderPass();
|
||||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, consumer_stages,
|
||||||
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
|
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
|
||||||
if (has_transform_feedback) {
|
if (has_transform_feedback) {
|
||||||
static constexpr VkMemoryBarrier XFB_OUTPUT_BARRIER{
|
static constexpr VkMemoryBarrier XFB_OUTPUT_BARRIER{
|
||||||
|
|||||||
@@ -961,6 +961,21 @@ FN_MAX_LIMIT_LIST
|
|||||||
return features2.features.multiViewport;
|
return features2.features.multiViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPipelineStageFlags AttachmentConsumerStages() const {
|
||||||
|
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||||
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||||
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||||
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
if (features2.features.geometryShader) {
|
||||||
|
stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
||||||
|
}
|
||||||
|
return stages;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the device supports VK_KHR_maintenance1.
|
/// Returns true if the device supports VK_KHR_maintenance1.
|
||||||
bool IsKhrMaintenance1Supported() const {
|
bool IsKhrMaintenance1Supported() const {
|
||||||
return extensions.maintenance1;
|
return extensions.maintenance1;
|
||||||
|
|||||||
Reference in New Issue
Block a user