tests/shader_runner: Add support for creating mipmapped textures.

This commit is contained in:
Zebediah Figura 2023-04-30 19:23:00 -05:00 committed by Alexandre Julliard
parent fd38c58112
commit c940486a89
Notes: Alexandre Julliard 2023-05-08 22:34:30 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/191
6 changed files with 111 additions and 39 deletions

View File

@ -251,6 +251,14 @@ static void parse_resource_directive(struct resource_params *resource, const cha
if (ret < 2) if (ret < 2)
fatal_error("Malformed texture size '%s'.\n", line); fatal_error("Malformed texture size '%s'.\n", line);
} }
else if (match_string(line, "levels", &line))
{
char *rest;
resource->level_count = strtoul(line, &rest, 10);
if (rest == line)
fatal_error("Malformed texture directive '%s'.\n", line);
}
else else
{ {
union union
@ -474,6 +482,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
params.texel_size = 16; params.texel_size = 16;
params.width = RENDER_TARGET_WIDTH; params.width = RENDER_TARGET_WIDTH;
params.height = RENDER_TARGET_HEIGHT; params.height = RENDER_TARGET_HEIGHT;
params.level_count = 1;
set_resource(runner, runner->ops->create_resource(runner, &params)); set_resource(runner, runner->ops->create_resource(runner, &params));
} }
@ -518,6 +527,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
params.texel_size = 16; params.texel_size = 16;
params.width = RENDER_TARGET_WIDTH; params.width = RENDER_TARGET_WIDTH;
params.height = RENDER_TARGET_HEIGHT; params.height = RENDER_TARGET_HEIGHT;
params.level_count = 1;
set_resource(runner, runner->ops->create_resource(runner, &params)); set_resource(runner, runner->ops->create_resource(runner, &params));
} }
@ -995,6 +1005,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT;
current_resource.texel_size = 16; current_resource.texel_size = 16;
current_resource.level_count = 1;
} }
else if (sscanf(line, "[texture %u]\n", &index)) else if (sscanf(line, "[texture %u]\n", &index))
{ {
@ -1007,6 +1018,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT;
current_resource.texel_size = 16; current_resource.texel_size = 16;
current_resource.level_count = 1;
} }
else if (sscanf(line, "[uav %u]\n", &index)) else if (sscanf(line, "[uav %u]\n", &index))
{ {
@ -1019,6 +1031,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT;
current_resource.texel_size = 16; current_resource.texel_size = 16;
current_resource.level_count = 1;
} }
else if (sscanf(line, "[vertex buffer %u]\n", &index)) else if (sscanf(line, "[vertex buffer %u]\n", &index))
{ {

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <float.h>
#include <stdint.h> #include <stdint.h>
#include "vkd3d_windows.h" #include "vkd3d_windows.h"
#include "vkd3d_d3dcommon.h" #include "vkd3d_d3dcommon.h"
@ -68,6 +69,7 @@ struct resource_params
enum texture_data_type data_type; enum texture_data_type data_type;
unsigned int texel_size; unsigned int texel_size;
unsigned int width, height; unsigned int width, height;
unsigned int level_count;
uint8_t *data; uint8_t *data;
size_t data_size, data_capacity; size_t data_size, data_capacity;
}; };
@ -134,6 +136,11 @@ struct shader_runner_ops
void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb); void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb);
}; };
static inline unsigned int get_level_dimension(unsigned int dimension, unsigned int level)
{
return max(1, dimension >> level);
}
void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2); void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2);
unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot); unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot);

View File

@ -338,7 +338,6 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
{ {
struct d3d11_shader_runner *runner = d3d11_shader_runner(r); struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
ID3D11Device *device = runner->device; ID3D11Device *device = runner->device;
D3D11_SUBRESOURCE_DATA resource_data;
struct d3d11_resource *resource; struct d3d11_resource *resource;
HRESULT hr; HRESULT hr;
@ -351,11 +350,15 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: case RESOURCE_TYPE_UAV:
{ {
D3D11_SUBRESOURCE_DATA resource_data[2];
D3D11_TEXTURE2D_DESC desc = {0}; D3D11_TEXTURE2D_DESC desc = {0};
if (params->level_count > ARRAY_SIZE(resource_data))
fatal_error("Level count %u is too high.\n", params->level_count);
desc.Width = params->width; desc.Width = params->width;
desc.Height = params->height; desc.Height = params->height;
desc.MipLevels = 1; desc.MipLevels = params->level_count;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.Format = params->format; desc.Format = params->format;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
@ -369,10 +372,19 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
if (params->data) if (params->data)
{ {
resource_data.pSysMem = params->data; unsigned int buffer_offset = 0;
resource_data.SysMemPitch = params->width * params->texel_size;
resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch; for (unsigned int level = 0; level < params->level_count; ++level)
hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &resource->texture); {
unsigned int level_width = get_level_dimension(params->width, level);
unsigned int level_height = get_level_dimension(params->height, level);
resource_data[level].pSysMem = &params->data[buffer_offset];
resource_data[level].SysMemPitch = level_width * params->texel_size;
resource_data[level].SysMemSlicePitch = level_height * resource_data[level].SysMemPitch;
buffer_offset += resource_data[level].SysMemSlicePitch;
}
hr = ID3D11Device_CreateTexture2D(device, &desc, resource_data, &resource->texture);
} }
else else
{ {

View File

@ -90,12 +90,27 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
struct test_context *test_context = &runner->test_context; struct test_context *test_context = &runner->test_context;
ID3D12Device *device = test_context->device; ID3D12Device *device = test_context->device;
D3D12_SUBRESOURCE_DATA resource_data; D3D12_SUBRESOURCE_DATA resource_data[2];
struct d3d12_resource *resource; struct d3d12_resource *resource;
unsigned int buffer_offset = 0;
if (params->level_count > ARRAY_SIZE(resource_data))
fatal_error("Level count %u is too high.\n", params->level_count);
resource = calloc(1, sizeof(*resource)); resource = calloc(1, sizeof(*resource));
init_resource(&resource->r, params); init_resource(&resource->r, params);
for (unsigned int level = 0; level < params->level_count; ++level)
{
unsigned int level_width = get_level_dimension(params->width, level);
unsigned int level_height = get_level_dimension(params->height, level);
resource_data[level].pData = &params->data[buffer_offset];
resource_data[level].RowPitch = level_width * params->texel_size;
resource_data[level].SlicePitch = level_height * resource_data[level].RowPitch;
buffer_offset += resource_data[level].SlicePitch;
}
switch (params->type) switch (params->type)
{ {
case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_RENDER_TARGET:
@ -106,7 +121,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
if (params->slot >= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT) if (params->slot >= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT)
fatal_error("RTV slot %u is too high.\n", params->slot); fatal_error("RTV slot %u is too high.\n", params->slot);
resource->resource = create_default_texture(device, params->width, params->height, resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count,
params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET); params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12Device_CreateRenderTargetView(device, resource->resource, ID3D12Device_CreateRenderTargetView(device, resource->resource,
NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot)); NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot));
@ -117,11 +132,10 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
runner->heap = create_gpu_descriptor_heap(device, runner->heap = create_gpu_descriptor_heap(device,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
resource->resource = create_default_texture(device, params->width, params->height, resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count,
params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
resource_data.pData = params->data; upload_texture_data(resource->resource, resource_data,
resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size; params->level_count, test_context->queue, test_context->list);
upload_texture_data(resource->resource, &resource_data, 1, test_context->queue, test_context->list);
reset_command_list(test_context->list, test_context->allocator); reset_command_list(test_context->list, test_context->allocator);
transition_resource_state(test_context->list, resource->resource, D3D12_RESOURCE_STATE_COPY_DEST, transition_resource_state(test_context->list, resource->resource, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
@ -134,11 +148,10 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
runner->heap = create_gpu_descriptor_heap(device, runner->heap = create_gpu_descriptor_heap(device,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
resource->resource = create_default_texture(device, params->width, params->height, resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count,
params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
resource_data.pData = params->data; upload_texture_data(resource->resource, resource_data,
resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size; params->level_count, test_context->queue, test_context->list);
upload_texture_data(resource->resource, &resource_data, 1, test_context->queue, test_context->list);
reset_command_list(test_context->list, test_context->allocator); reset_command_list(test_context->list, test_context->allocator);
transition_resource_state(test_context->list, resource->resource, transition_resource_state(test_context->list, resource->resource,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
@ -236,6 +249,7 @@ static ID3D12RootSignature *d3d12_runner_create_root_signature(struct d3d12_shad
sampler_desc->AddressU = sampler->u_address; sampler_desc->AddressU = sampler->u_address;
sampler_desc->AddressV = sampler->v_address; sampler_desc->AddressV = sampler->v_address;
sampler_desc->AddressW = sampler->w_address; sampler_desc->AddressW = sampler->w_address;
sampler_desc->MaxLOD = FLT_MAX;
sampler_desc->ShaderRegister = sampler->slot; sampler_desc->ShaderRegister = sampler->slot;
sampler_desc->RegisterSpace = 0; sampler_desc->RegisterSpace = 0;
sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;

View File

@ -190,7 +190,6 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con
struct d3d9_shader_runner *runner = d3d9_shader_runner(r); struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
IDirect3DDevice9 *device = runner->device; IDirect3DDevice9 *device = runner->device;
struct d3d9_resource *resource; struct d3d9_resource *resource;
unsigned int src_pitch, y;
D3DLOCKED_RECT map_desc; D3DLOCKED_RECT map_desc;
D3DFORMAT format; D3DFORMAT format;
HRESULT hr; HRESULT hr;
@ -223,18 +222,32 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con
break; break;
case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_TEXTURE:
{
unsigned int src_buffer_offset = 0;
hr = IDirect3DDevice9_CreateTexture(device, params->width, params->height, hr = IDirect3DDevice9_CreateTexture(device, params->width, params->height,
1, D3DUSAGE_DYNAMIC, format, D3DPOOL_DEFAULT, &resource->texture, NULL); params->level_count, 0, format, D3DPOOL_MANAGED, &resource->texture, NULL);
ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr); ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
hr = IDirect3DTexture9_LockRect(resource->texture, 0, &map_desc, NULL, D3DLOCK_DISCARD); for (unsigned int level = 0; level < params->level_count; ++level)
ok(hr == D3D_OK, "Failed to map texture, hr %#lx.\n", hr); {
src_pitch = params->width * params->texel_size; unsigned int level_width = get_level_dimension(params->width, level);
for (y = 0; y < params->height; ++y) unsigned int level_height = get_level_dimension(params->height, level);
memcpy((char *)map_desc.pBits + y * map_desc.Pitch, params->data + y * src_pitch, src_pitch); unsigned int src_row_pitch = level_width * params->texel_size;
hr = IDirect3DTexture9_UnlockRect(resource->texture, 0); unsigned int src_slice_pitch = level_height * src_row_pitch;
ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr);
hr = IDirect3DTexture9_LockRect(resource->texture, level, &map_desc, NULL, 0);
ok(hr == D3D_OK, "Failed to map texture, hr %#lx.\n", hr);
for (unsigned int y = 0; y < level_height; ++y)
memcpy(&((char *)map_desc.pBits)[y * map_desc.Pitch],
&params->data[src_buffer_offset + y * src_row_pitch], src_row_pitch);
hr = IDirect3DTexture9_UnlockRect(resource->texture, level);
ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr);
src_buffer_offset += src_slice_pitch;
}
break; break;
}
case RESOURCE_TYPE_UAV: case RESOURCE_TYPE_UAV:
fatal_error("UAVs are not supported.\n"); fatal_error("UAVs are not supported.\n");

View File

@ -114,7 +114,7 @@ static void transition_image_layout(struct vulkan_shader_runner *runner,
barrier.image = image; barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1; barrier.subresourceRange.layerCount = 1;
@ -178,7 +178,7 @@ static VkBuffer create_buffer(const struct vulkan_shader_runner *runner, VkDevic
} }
static VkImage create_2d_image(const struct vulkan_shader_runner *runner, uint32_t width, uint32_t height, static VkImage create_2d_image(const struct vulkan_shader_runner *runner, uint32_t width, uint32_t height,
VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory) uint32_t level_count, VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory)
{ {
VkImageCreateInfo image_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; VkImageCreateInfo image_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
VkMemoryRequirements memory_reqs; VkMemoryRequirements memory_reqs;
@ -189,7 +189,7 @@ static VkImage create_2d_image(const struct vulkan_shader_runner *runner, uint32
image_info.extent.width = width; image_info.extent.width = width;
image_info.extent.height = height; image_info.extent.height = height;
image_info.extent.depth = 1; image_info.extent.depth = 1;
image_info.mipLevels = 1; image_info.mipLevels = level_count;
image_info.arrayLayers = 1; image_info.arrayLayers = 1;
image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
@ -220,7 +220,7 @@ static VkImageView create_2d_image_view(const struct vulkan_shader_runner *runne
view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_info.subresourceRange.baseMipLevel = 0; view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1; view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
view_info.subresourceRange.baseArrayLayer = 0; view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1; view_info.subresourceRange.layerCount = 1;
@ -234,7 +234,6 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
struct vulkan_resource *resource; struct vulkan_resource *resource;
VkDevice device = runner->device; VkDevice device = runner->device;
VkBufferImageCopy region = {0};
VkDeviceMemory staging_memory; VkDeviceMemory staging_memory;
VkBuffer staging_buffer; VkBuffer staging_buffer;
VkFormat format; VkFormat format;
@ -248,7 +247,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_RENDER_TARGET:
format = vkd3d_get_vk_format(params->format); format = vkd3d_get_vk_format(params->format);
resource->image = create_2d_image(runner, params->width, params->height, resource->image = create_2d_image(runner, params->width, params->height, params->level_count,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory); VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory);
resource->view = create_2d_image_view(runner, resource->image, format); resource->view = create_2d_image_view(runner, resource->image, format);
@ -263,6 +262,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
{ {
VkImageUsageFlagBits usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; VkImageUsageFlagBits usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
unsigned int buffer_offset = 0;
format = vkd3d_get_vk_format(params->format); format = vkd3d_get_vk_format(params->format);
@ -272,7 +272,8 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
} }
resource->image = create_2d_image(runner, params->width, params->height, usage, format, &resource->memory); resource->image = create_2d_image(runner, params->width, params->height, params->level_count,
usage, format, &resource->memory);
resource->view = create_2d_image_view(runner, resource->image, format); resource->view = create_2d_image_view(runner, resource->image, format);
staging_buffer = create_buffer(runner, params->data_size, staging_buffer = create_buffer(runner, params->data_size,
@ -286,13 +287,24 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
transition_image_layout(runner, resource->image, transition_image_layout(runner, resource->image,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; for (unsigned int level = 0; level < params->level_count; ++level)
region.imageSubresource.layerCount = 1; {
region.imageExtent.width = params->width; unsigned int level_width = get_level_dimension(params->width, level);
region.imageExtent.height = params->height; unsigned int level_height = get_level_dimension(params->height, level);
region.imageExtent.depth = 1; VkBufferImageCopy region = {0};
VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region)); region.bufferOffset = buffer_offset;
region.imageSubresource.mipLevel = level;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.layerCount = 1;
region.imageExtent.width = level_width;
region.imageExtent.height = level_height;
region.imageExtent.depth = 1;
VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
buffer_offset += level_width * level_height * params->texel_size;
}
transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout); transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
@ -739,6 +751,7 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r
sampler_desc.addressModeU = vk_address_mode_from_d3d12(sampler->u_address); sampler_desc.addressModeU = vk_address_mode_from_d3d12(sampler->u_address);
sampler_desc.addressModeV = vk_address_mode_from_d3d12(sampler->v_address); sampler_desc.addressModeV = vk_address_mode_from_d3d12(sampler->v_address);
sampler_desc.addressModeW = vk_address_mode_from_d3d12(sampler->w_address); sampler_desc.addressModeW = vk_address_mode_from_d3d12(sampler->w_address);
sampler_desc.maxLod = FLT_MAX;
VK_CALL(vkCreateSampler(runner->device, &sampler_desc, NULL, &vulkan_sampler->vk_sampler)); VK_CALL(vkCreateSampler(runner->device, &sampler_desc, NULL, &vulkan_sampler->vk_sampler));
vulkan_sampler->binding = binding_index++; vulkan_sampler->binding = binding_index++;