[PATCH vkd3d 4/4] tests: Introduce a Vulkan shader runner.

Zebediah Figura zfigura at codeweavers.com
Tue Apr 12 11:42:10 CDT 2022


On 4/12/22 06:16, Henri Verbeet wrote:
> I only did a cursory review, with the idea that for something like
> this, unless there's something especially egregious, it's fine to fix
> things up after the fact. A couple of things did stand out though:
> 
> On Mon, 11 Apr 2022 at 19:35, Zebediah Figura <zfigura at codeweavers.com> wrote:
>> diff --git a/tests/shader_runner.c b/tests/shader_runner.c
>> index bf3bc0d85..54b667fc7 100644
>> --- a/tests/shader_runner.c
>> +++ b/tests/shader_runner.c
>> @@ -856,6 +856,8 @@ START_TEST(shader_runner)
>>   #ifdef _WIN32
>>       run_shader_tests_d3d9(argc, argv);
>>       run_shader_tests_d3d11(argc, argv);
>> +#else
>> +    run_shader_tests_vulkan(argc, argv);
>>   #endif
>>       run_shader_tests_d3d12(argc, argv);
>>   }
> 
> I theory, Windows has Vulkan too.

Indeed. The intention here is to avoid building crosstests, but that's 
the wrong way to check for it...

> 
> Now that we have multiple shader runners, the logs can become less
> than clear; vkd3d_test_check_ok() uses "vkd3d_test_name" as prefix,
> but that's "shader_runner" for all of these. We may want to consider
> setting that to e.g. "shader_runner_d3d12" for the d3d12 runner, and
> so on.

Modifying vkd3d_test_name sounds like a good idea.

> 
>> +static void transition_image_layout(struct vulkan_shader_runner *runner,
>> +        VkImage image, VkImageLayout src_layout, VkImageLayout dst_layout)
>> +{
>> +    VkImageMemoryBarrier barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
>> +
>> +    barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
>> +    barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
>> +    barrier.oldLayout = src_layout;
>> +    barrier.newLayout = dst_layout;
>> +    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
>> +    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
>> +    barrier.image = image;
>> +    barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
>> +    barrier.subresourceRange.baseMipLevel = 0;
>> +    barrier.subresourceRange.levelCount = 1;
>> +    barrier.subresourceRange.baseArrayLayer = 0;
>> +    barrier.subresourceRange.layerCount = 1;
>> +
>> +    VK_CALL(vkCmdPipelineBarrier(runner->cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
>> +            VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0, NULL, 1, &barrier));
>> +}
> 
> That function is a fair bit less generic than its name might suggest.

I suppose so, although in what respect do you mean specifically?

> 
>> +static bool compile_shader(const struct vulkan_shader_runner *runner, const char *source, const char *type,
>> +        struct vkd3d_shader_code *dxbc, struct vkd3d_shader_code *spirv)
>> +{
> [...]
>> +    info.next = &hlsl_info;
>> +    info.source.code = source;
>> +    info.source.size = strlen(source);
>> +    info.source_type = VKD3D_SHADER_SOURCE_HLSL;
>> +    info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
>> +    info.log_level = VKD3D_SHADER_LOG_WARNING;
> [...]
>> +    info.next = &spirv_info;
>> +    info.source = *dxbc;
>> +    info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
>> +    info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
> 
> It should be relatively straightforward for vkd3d-shader to support
> compiling HLSL to SPIR-V. There may be a case for a more direct path,
> but for a start, compile_hlsl() could essentially just do what we're
> doing here.

Yes, although in this case we need to reflect the DXBC anyway, in order 
to retrieve vertex attribute bindings.

> 
>> +static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_runner *runner)
>> +{
> [...]
>> +    for (i = 0; i < runner->r.sampler_count; ++i)
>> +    {
>> +        VkSamplerCreateInfo sampler_desc = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
>> +        struct vulkan_sampler *vulkan_sampler = &runner->samplers[i];
>> +        const struct sampler *sampler = &runner->r.samplers[i];
>> +
>> +        sampler_desc.magFilter = (sampler->filter & 0x4) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
>> +        sampler_desc.minFilter = (sampler->filter & 0x1) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
>> +        sampler_desc.mipmapMode = (sampler->filter & 0x10) ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
>> +        sampler_desc.addressModeU = vk_address_mode_from_d3d12(sampler->u_address);
>> +        sampler_desc.addressModeV = vk_address_mode_from_d3d12(sampler->v_address);
>> +        sampler_desc.addressModeW = vk_address_mode_from_d3d12(sampler->w_address);
> 
> We may want to consider storing the filter modes separately to begin
> with, but if we're going to store these as D3D12_FILTER values, it
> would make sense to use the appropriate macros like
> D3D12_DECODE_MAG_FILTER to decode them as well.

Sure, that makes sense.

> 
>> +static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPoint bind_point,
>> +        VkDescriptorSetLayout set_layout, VkPipelineLayout pipeline_layout)
>> +{
> [...]
>> +    if (runner->r.uniform_count)
>> +        VK_CALL(vkCmdPushConstants(cmd_buffer, pipeline_layout, VK_SHADER_STAGE_ALL, 0,
>> +                runner->r.uniform_count * sizeof(*runner->r.uniforms), runner->r.uniforms));
> 
> Note that the number of available push constants is typically somewhat
> limited. A value of 128 (= 32 * float = 8 * vec4) for
> maxPushConstantsSize is not uncommon. That's probably sufficient for
> our purposes, but nevertheless something to be aware of. It's
> certainly a lot less than e.g. d3d9's 256 vec4 constants.

I'll add a check to make sure we don't exceed the limits.



More information about the wine-devel mailing list