mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
Derivative opcodes require Fragment exec model
Added validator check that all derivative opcodes require Fragment execution model.
This commit is contained in:
parent
c170afd93b
commit
d8b2013ecf
@ -52,8 +52,10 @@ spv_result_t DerivativesPass(ValidationState_t& _,
|
|||||||
<< spvOpcodeString(opcode);
|
<< spvOpcodeString(opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All derivative opcodes require Fragment execution model.
|
_.current_function().RegisterExecutionModelLimitation(
|
||||||
// This needs to be checked elsewhere.
|
SpvExecutionModelFragment, std::string(
|
||||||
|
"Derivative instructions require Fragment execution model: ") +
|
||||||
|
spvOpcodeString(opcode));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
@ -27,17 +28,19 @@ using ValidateDerivatives = spvtest::ValidateBase<bool>;
|
|||||||
|
|
||||||
std::string GenerateShaderCode(
|
std::string GenerateShaderCode(
|
||||||
const std::string& body,
|
const std::string& body,
|
||||||
const std::string& capabilities_and_extensions = "") {
|
const std::string& capabilities_and_extensions = "",
|
||||||
const std::string capabilities =
|
const std::string& execution_model = "Fragment") {
|
||||||
R"(
|
std::stringstream ss;
|
||||||
|
ss << R"(
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpCapability DerivativeControl)";
|
OpCapability DerivativeControl
|
||||||
|
)";
|
||||||
|
|
||||||
const std::string after_extension_before_body =
|
ss << capabilities_and_extensions;
|
||||||
R"(
|
ss << "OpMemoryModel Logical GLSL450\n";
|
||||||
%ext_inst = OpExtInstImport "GLSL.std.450"
|
ss << "OpEntryPoint " << execution_model << " %main \"main\"\n";
|
||||||
OpMemoryModel Logical GLSL450
|
|
||||||
OpEntryPoint Fragment %main "main"
|
ss << R"(
|
||||||
%void = OpTypeVoid
|
%void = OpTypeVoid
|
||||||
%func = OpTypeFunction %void
|
%func = OpTypeFunction %void
|
||||||
%bool = OpTypeBool
|
%bool = OpTypeBool
|
||||||
@ -53,15 +56,16 @@ OpEntryPoint Fragment %main "main"
|
|||||||
%f32vec4_var_input = OpVariable %f32vec4_ptr_input Input
|
%f32vec4_var_input = OpVariable %f32vec4_ptr_input Input
|
||||||
|
|
||||||
%main = OpFunction %void None %func
|
%main = OpFunction %void None %func
|
||||||
%main_entry = OpLabel)";
|
%main_entry = OpLabel
|
||||||
|
)";
|
||||||
|
|
||||||
const std::string after_body =
|
ss << body;
|
||||||
R"(
|
|
||||||
|
ss << R"(
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd)";
|
OpFunctionEnd)";
|
||||||
|
|
||||||
return capabilities + capabilities_and_extensions +
|
return ss.str();
|
||||||
after_extension_before_body + body + after_body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidateDerivatives, ScalarSuccess) {
|
TEST_F(ValidateDerivatives, ScalarSuccess) {
|
||||||
@ -126,4 +130,16 @@ TEST_F(ValidateDerivatives, OpDPdxWrongPType) {
|
|||||||
"DPdx"));
|
"DPdx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ValidateDerivatives, OpDPdxWrongExecutionModel) {
|
||||||
|
const std::string body = R"(
|
||||||
|
%f32vec4_var = OpLoad %f32vec4 %f32vec4_var_input
|
||||||
|
%val1 = OpDPdx %f32vec4 %f32vec4_var
|
||||||
|
)";
|
||||||
|
|
||||||
|
CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
|
||||||
|
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||||
|
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||||
|
"Derivative instructions require Fragment execution model: DPdx"));
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user