diff options
Diffstat (limited to 'src/video_core/vertex_shader.cpp')
-rw-r--r-- | src/video_core/vertex_shader.cpp | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index 7d68998f..87006a83 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp @@ -119,17 +119,13 @@ static void ProcessShaderCode(VertexShaderState& state) { switch (instr.opcode.Value().GetInfo().type) { case OpCode::Type::Arithmetic: { - bool is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed); - // TODO: We don't really support this properly: For instance, the address register - // offset needs to be applied to SRC2 instead, etc. - // For now, we just abort in this situation. - ASSERT_MSG(!is_inverted, "Bad condition..."); + const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); const int address_offset = (instr.common.address_register_index == 0) ? 0 : state.address_registers[instr.common.address_register_index - 1]; - const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + address_offset); - const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted)); + const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + (!is_inverted * address_offset)); + const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + ( is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); @@ -208,6 +204,15 @@ static void ProcessShaderCode(VertexShaderState& state) { } break; + case OpCode::Id::MIN: + for (int i = 0; i < 4; ++i) { + if (!swizzle.DestComponentEnabled(i)) + continue; + + dest[i] = std::min(src1[i], src2[i]); + } + break; + case OpCode::Id::DP3: case OpCode::Id::DP4: { @@ -279,6 +284,16 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } + case OpCode::Id::SLT: + case OpCode::Id::SLTI: + for (int i = 0; i < 4; ++i) { + if (!swizzle.DestComponentEnabled(i)) + continue; + + dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + } + break; + case OpCode::Id::CMP: for (int i = 0; i < 2; ++i) { // TODO: Can you restrict to one compare via dest masking? @@ -330,7 +345,7 @@ static void ProcessShaderCode(VertexShaderState& state) { case OpCode::Type::MultiplyAdd: { - if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) || + if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) || (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) { const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id]; @@ -547,7 +562,7 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes) { const auto& attribute_register_map = regs.vs_input_register_map; float24 dummy_register; boost::fill(state.input_register_table, &dummy_register); - + if (num_attributes > 0) state.input_register_table[attribute_register_map.attribute0_register] = &input.attr[0].x; if (num_attributes > 1) state.input_register_table[attribute_register_map.attribute1_register] = &input.attr[1].x; if (num_attributes > 2) state.input_register_table[attribute_register_map.attribute2_register] = &input.attr[2].x; |