blob: e463b1bebd80d76e834f9519b3d685c2f6ad9f6a [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Functional tests using vkrunner
*//*--------------------------------------------------------------------*/
#include <assert.h>
#include <vkrunner/vkrunner.h>
#include "vktVkRunnerTestCase.hpp"
#include "tcuTestLog.hpp"
namespace vkt
{
namespace vkrunner
{
static const char *
vr_stage_name[VR_SHADER_STAGE_N_STAGES] = {
"vertex",
"tess_ctrl",
"tess_eval",
"geometry",
"fragment",
"compute",
};
static void errorCb(const char* message,
void* user_data)
{
VkRunnerTestCase* test = (VkRunnerTestCase*) user_data;
test->getTestContext().getLog()
<< tcu::TestLog::Message
<< message
<< "\n"
<< tcu::TestLog::EndMessage;
}
VkRunnerTestCase::VkRunnerTestCase (tcu::TestContext& testCtx,
const char* categoryname,
const char* filename,
const char* name,
const char* description)
: TestCase(testCtx, name, description)
{
m_testCaseData.categoryname = categoryname;
m_testCaseData.filename = filename;
m_testCaseData.num_shaders = 0;
m_testCaseData.script = DE_NULL;
m_testCaseData.shaders = DE_NULL;
std::string readFilename("vulkan/vkrunner/");
readFilename.append(m_testCaseData.categoryname);
readFilename.append("/");
readFilename.append(m_testCaseData.filename);
m_testCaseData.source = vr_source_from_file(readFilename.c_str());
}
VkRunnerTestCase::~VkRunnerTestCase (void)
{
if (m_testCaseData.num_shaders)
{
for (int i = 0; i < m_testCaseData.num_shaders; i++)
{
/* shaders[i]->source were allocated by VkRunner. We don't need them anymore. */
deFree(m_testCaseData.shaders[i].source);
}
deFree(m_testCaseData.shaders);
}
if (m_testCaseData.script)
vr_script_free(m_testCaseData.script);
if (m_testCaseData.source)
vr_source_free(m_testCaseData.source);
}
void VkRunnerTestCase::addTokenReplacement(const char *token,
const char *replacement)
{
vr_source_add_token_replacement(m_testCaseData.source,
token,
replacement);
}
bool VkRunnerTestCase::getShaders()
{
/* Create a temporary vr_config to log shader_test parsing errors to test's log file */
struct vr_config *config = vr_config_new();
vr_config_set_user_data(config, this);
vr_config_set_error_cb(config, errorCb);
m_testCaseData.script = vr_script_load(config, m_testCaseData.source);
if (m_testCaseData.script == DE_NULL)
{
/* Parser returned an error or shader_test file doesn't exist */
vr_config_free(config);
return false;
}
m_testCaseData.num_shaders = vr_script_get_num_shaders(m_testCaseData.script);
m_testCaseData.shaders = (struct vr_script_shader_code *)
malloc(sizeof(struct vr_script_shader_code)*m_testCaseData.num_shaders);
vr_script_get_shaders(m_testCaseData.script,
m_testCaseData.source,
m_testCaseData.shaders);
vr_config_free(config);
return true;
}
TestInstance* VkRunnerTestCase::createInstance(Context& ctx) const
{
if (m_testCaseData.script == DE_NULL)
TCU_THROW(InternalError, "Could not find script file");
return new VkRunnerTestInstance(ctx, m_testCaseData);
}
void VkRunnerTestCase::initPrograms(vk::SourceCollections& programCollection) const
{
int num_shader[VR_SHADER_STAGE_N_STAGES] = {0};
for (int i = 0; i < m_testCaseData.num_shaders; i++)
{
num_shader[m_testCaseData.shaders[i].stage]++;
if (num_shader[m_testCaseData.shaders[i].stage] > 1)
TCU_THROW(InternalError, "Multiple shaders per stage are not currently supported");
/* We ignore the SPIR-V shaders in binary form */
if (m_testCaseData.shaders[i].source_type == VR_SCRIPT_SOURCE_TYPE_GLSL)
{
switch (m_testCaseData.shaders[i].stage)
{
case VR_SHADER_STAGE_VERTEX:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::VertexSource(m_testCaseData.shaders[i].source);
break;
case VR_SHADER_STAGE_TESS_CTRL:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::TessellationControlSource(m_testCaseData.shaders[i].source);
break;
case VR_SHADER_STAGE_TESS_EVAL:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::TessellationEvaluationSource(m_testCaseData.shaders[i].source);
break;
case VR_SHADER_STAGE_GEOMETRY:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::GeometrySource(m_testCaseData.shaders[i].source);
break;
case VR_SHADER_STAGE_FRAGMENT:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::FragmentSource(m_testCaseData.shaders[i].source);
break;
case VR_SHADER_STAGE_COMPUTE:
programCollection.glslSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << glu::ComputeSource(m_testCaseData.shaders[i].source);
break;
default:
assert(0 && "Shader type is not supported");
}
} else if (m_testCaseData.shaders[i].source_type == VR_SCRIPT_SOURCE_TYPE_SPIRV)
{
programCollection.spirvAsmSources.add(vr_stage_name[m_testCaseData.shaders[i].stage]) << m_testCaseData.shaders[i].source;
}
}
}
tcu::TestStatus VkRunnerTestInstance::iterate (void)
{
/* Get the compiled version of the text-based shaders and replace them */
for (int stage = 0; stage < VR_SHADER_STAGE_N_STAGES; stage++)
{
std::string name(vr_stage_name[stage]);
if (!m_context.getBinaryCollection().contains(name))
continue;
size_t source_length = m_context.getBinaryCollection().get(name).getSize();
unsigned *source = (unsigned *) deMalloc(source_length);
deMemcpy(source,
m_context.getBinaryCollection().get(name).getBinary(),
source_length);
vr_script_replace_shaders_stage_binary(m_testCaseData.script,
(enum vr_shader_stage)stage,
source_length,
source);
deFree(source);
}
/* Replace text-based shaders by their binary equivalent and execute the test */
vr_result res = vr_executor_execute_script(m_context.getExecutor(), m_testCaseData.script);
switch (res)
{
case VR_RESULT_FAIL:
return tcu::TestStatus::fail("Fail");
case VR_RESULT_PASS:
return tcu::TestStatus::pass("Pass");
case VR_RESULT_SKIP:
return tcu::TestStatus::incomplete();
}
return tcu::TestStatus::fail("Fail");
}
} // vkrunner
} // vkt