From cc340b2838ba7780f6cff9b37961971fa6e403d7 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 23 Oct 2024 22:12:25 +0200 Subject: [PATCH] tests/shader_runner: Handle render target sizes other than 640x480. --- tests/shader_runner_d3d11.c | 38 +++++++++++++++++++++++++++--------- tests/shader_runner_d3d12.c | 14 ++++++++++++- tests/shader_runner_d3d9.c | 27 ++++++++++++++++++++++++- tests/shader_runner_gl.c | 16 ++++++++++++--- tests/shader_runner_vulkan.c | 22 +++++++++++++-------- 5 files changed, 95 insertions(+), 22 deletions(-) diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 7a8832da..5ce4b81f 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -75,6 +75,22 @@ static struct d3d11_shader_runner *d3d11_shader_runner(struct shader_runner *r) return CONTAINING_RECORD(r, struct d3d11_shader_runner, r); } +static void set_viewport(ID3D11DeviceContext *context, float x, float y, + float width, float height, float min_depth, float max_depth) +{ + D3D11_VIEWPORT vp = + { + .TopLeftX = x, + .TopLeftY = y, + .Width = width, + .Height = height, + .MinDepth = min_depth, + .MaxDepth = max_depth, + }; + + ID3D11DeviceContext_RSSetViewports(context, 1, &vp); +} + static IDXGIAdapter *create_adapter(void) { IDXGIFactory4 *factory4; @@ -247,7 +263,6 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) D3D11_FEATURE_DATA_DOUBLES doubles = {0}; unsigned int rt_width, rt_height; D3D11_RASTERIZER_DESC rs_desc; - D3D11_VIEWPORT vp; HRESULT hr; RECT rect; @@ -310,13 +325,7 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) ID3D11Device_GetImmediateContext(runner->device, &runner->immediate_context); - vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = rt_width; - vp.Height = rt_height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(runner->immediate_context, 1, &vp); + set_viewport(runner->immediate_context, 0.0f, 0.0f, rt_width, rt_height, 0.0f, 1.0f); rs_desc.FillMode = D3D11_FILL_SOLID; rs_desc.CullMode = D3D11_CULL_NONE; @@ -670,12 +679,12 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11RenderTargetView *rtvs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; + unsigned int fb_width, fb_height, rtv_count = 0; unsigned int min_uav_slot = ARRAY_SIZE(uavs); ID3D11DepthStencilState *ds_state = NULL; D3D11_DEPTH_STENCIL_DESC ds_desc = {0}; ID3D11Device *device = runner->device; ID3D11DepthStencilView *dsv = NULL; - unsigned int rtv_count = 0; ID3D11GeometryShader *gs; ID3D11Buffer *cb = NULL; ID3D11VertexShader *vs; @@ -770,6 +779,8 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11DeviceContext_GSSetConstantBuffers(context, 0, 1, &cb); } + fb_width = ~0u; + fb_height = ~0u; for (i = 0; i < runner->r.resource_count; ++i) { struct d3d11_resource *resource = d3d11_resource(runner->r.resources[i]); @@ -781,6 +792,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_RENDER_TARGET: rtvs[resource->r.desc.slot] = resource->rtv; rtv_count = max(rtv_count, resource->r.desc.slot + 1); + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_DEPTH_STENCIL: @@ -791,6 +806,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, hr = ID3D11Device_CreateDepthStencilState(device, &ds_desc, &ds_state); ok(hr == S_OK, "Failed to create depth/stencil state, hr %#lx.\n", hr); ID3D11DeviceContext_OMSetDepthStencilState(context, ds_state, 0); + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_TEXTURE: @@ -862,6 +881,7 @@ static bool d3d11_runner_draw(struct shader_runner *r, if (gs_code) ID3D11DeviceContext_GSSetShader(context, gs, NULL, 0); ID3D11DeviceContext_RSSetState(context, runner->rasterizer_state); + set_viewport(context, 0.0f, 0.0f, fb_width, fb_height, 0.0f, 1.0f); ID3D11DeviceContext_DrawInstanced(context, vertex_count, instance_count, 0, 0); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 894329c3..5624ce82 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -740,10 +740,10 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D10Blob *vs_code, *ps_code, *hs_code = NULL, *ds_code = NULL, *gs_code = NULL; D3D12_CPU_DESCRIPTOR_HANDLE rtvs[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; ID3D12GraphicsCommandList1 *command_list1 = test_context->list1; + unsigned int uniform_index, fb_width, fb_height, rtv_count = 0; ID3D12GraphicsCommandList *command_list = test_context->list; ID3D12CommandQueue *queue = test_context->queue; ID3D12Device *device = test_context->device; - unsigned int uniform_index, rtv_count = 0; D3D12_CPU_DESCRIPTOR_HANDLE dsv = {0}; ID3D12PipelineState *pso; bool succeeded; @@ -811,6 +811,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, add_pso(test_context, pso); + fb_width = ~0u; + fb_height = ~0u; ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, test_context->root_signature); if (runner->r.uniform_count) ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index, @@ -827,10 +829,18 @@ static bool d3d12_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_RENDER_TARGET: rtvs[resource->r.desc.slot] = get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.desc.slot); rtv_count = max(rtv_count, resource->r.desc.slot + 1); + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_DEPTH_STENCIL: dsv = get_cpu_dsv_handle(test_context, runner->dsv_heap, 0); + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_TEXTURE: @@ -859,7 +869,9 @@ static bool d3d12_runner_draw(struct shader_runner *r, if (runner->r.depth_bounds) ID3D12GraphicsCommandList1_OMSetDepthBounds(command_list1, runner->r.depth_min, runner->r.depth_max); + set_rect(&test_context->scissor_rect, 0, 0, fb_width, fb_height); ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect); + set_viewport(&test_context->viewport, 0.0f, 0.0f, fb_width, fb_height, 0.0f, 1.0f); ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, primitive_topology); ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 4ea90488..3c210a00 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -57,6 +57,22 @@ static struct d3d9_shader_runner *d3d9_shader_runner(struct shader_runner *r) static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT sdk_version); +static HRESULT set_viewport(IDirect3DDevice9 *device, unsigned int x, unsigned int y, + unsigned int width, unsigned int height, float min_depth, float max_depth) +{ + D3DVIEWPORT9 vp = + { + .X = x, + .Y = y, + .Width = width, + .Height = height, + .MinZ = min_depth, + .MaxZ = max_depth, + }; + + return IDirect3DDevice9_SetViewport(device, &vp); +} + static void init_adapter_info(void) { D3DADAPTER_IDENTIFIER9 identifier; @@ -329,11 +345,11 @@ static bool d3d9_runner_draw(struct shader_runner *r, struct d3d9_shader_runner *runner = d3d9_shader_runner(r); IDirect3DVertexDeclaration9 *vertex_declaration; IDirect3DDevice9 *device = runner->device; + unsigned int fb_width, fb_height, i, j; D3DVERTEXELEMENT9 *decl_elements; ID3D10Blob *vs_code, *ps_code; IDirect3DVertexShader9 *vs; IDirect3DPixelShader9 *ps; - unsigned int i, j; HRESULT hr; if (instance_count > 1) @@ -375,6 +391,8 @@ static bool d3d9_runner_draw(struct shader_runner *r, } decl_elements[runner->r.input_element_count] = decl_element_end; + fb_width = ~0u; + fb_height = ~0u; for (i = 0; i < runner->r.resource_count; ++i) { struct d3d9_resource *resource = d3d9_resource(runner->r.resources[i]); @@ -385,6 +403,10 @@ static bool d3d9_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_RENDER_TARGET: hr = IDirect3DDevice9_SetRenderTarget(device, resource->r.desc.slot, resource->surface); ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr); + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_DEPTH_STENCIL: @@ -416,6 +438,9 @@ static bool d3d9_runner_draw(struct shader_runner *r, } } + hr = set_viewport(device, 0, 0, fb_width, fb_height, 0.0f, 1.0f); + ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr); + for (i = 0; i < runner->r.sampler_count; ++i) { const struct sampler *sampler = &runner->r.samplers[i]; diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index 1c415a14..e03ff07a 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -1038,8 +1038,8 @@ static void gl_runner_clear(struct shader_runner *r, struct resource *res, const static bool gl_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY topology, unsigned int vertex_count, unsigned int instance_count) { + unsigned int attribute_idx, fb_width, fb_height, rt_count, i, j; struct vkd3d_shader_signature vs_input_signature; - unsigned int attribute_idx, rt_count, i, j; struct gl_runner *runner = gl_runner(r); struct vkd3d_shader_code vs_dxbc; uint8_t *attribute_offsets[32]; @@ -1123,6 +1123,8 @@ static bool gl_runner_draw(struct shader_runner *r, glBindSampler(s->binding.binding, sampler_info[sampler - r->samplers].id); } + fb_width = ~0u; + fb_height = ~0u; memset(vbo_info, 0, sizeof(vbo_info)); memset(draw_buffers, 0, sizeof(draw_buffers)); for (i = 0, rt_count = 0; i < runner->r.resource_count; ++i) @@ -1138,6 +1140,10 @@ static bool gl_runner_draw(struct shader_runner *r, draw_buffers[resource->r.desc.slot] = GL_COLOR_ATTACHMENT0 + resource->r.desc.slot; if (resource->r.desc.slot >= rt_count) rt_count = resource->r.desc.slot + 1; + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_DEPTH_STENCIL: @@ -1150,6 +1156,10 @@ static bool gl_runner_draw(struct shader_runner *r, glEnable(GL_DEPTH_BOUNDS_TEST_EXT); p_glDepthBoundsEXT(runner->r.depth_min, runner->r.depth_max); } + if (resource->r.desc.width < fb_width) + fb_width = resource->r.desc.width; + if (resource->r.desc.height < fb_height) + fb_height = resource->r.desc.height; break; case RESOURCE_TYPE_TEXTURE: @@ -1185,8 +1195,8 @@ static bool gl_runner_draw(struct shader_runner *r, glEnable(GL_SAMPLE_MASK); glSampleMaski(0, runner->r.sample_mask); - glViewport(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT); - glScissor(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT); + glViewport(0, 0, fb_width, fb_height); + glScissor(0, 0, fb_width, fb_height); glDrawBuffers(rt_count, draw_buffers); vs_dxbc.code = ID3D10Blob_GetBufferPointer(vs_blob); diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 6ce8977c..079171e2 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -59,6 +59,7 @@ struct vulkan_shader_runner ID3D10Blob *d3d_blobs[SHADER_TYPE_COUNT]; struct vkd3d_shader_scan_signature_info signatures[SHADER_TYPE_COUNT]; + VkExtent2D rt_size; struct vulkan_sampler { @@ -570,15 +571,15 @@ static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, VkPipelineVertexInputStateCreateInfo input_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO}; VkPipelineColorBlendStateCreateInfo blend_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}; VkPipelineMultisampleStateCreateInfo ms_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO}; - VkViewport viewport = {.y = RENDER_TARGET_HEIGHT, - .width = RENDER_TARGET_WIDTH, .height = -RENDER_TARGET_HEIGHT, .maxDepth = 1}; VkPipelineViewportStateCreateInfo vp_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO}; - static const VkRect2D rt_rect = {.extent.width = RENDER_TARGET_WIDTH, .extent.height = RENDER_TARGET_HEIGHT}; VkGraphicsPipelineCreateInfo pipeline_desc = {.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; + VkViewport viewport = {.y = runner->rt_size.height, .width = runner->rt_size.width, + .height = -(float)runner->rt_size.height, .maxDepth = 1}; VkPipelineColorBlendAttachmentState attachment_desc[MAX_RESOURCES] = {0}; const struct vulkan_test_context *context = &runner->context; VkPipelineTessellationStateCreateInfo tessellation_info; VkVertexInputAttributeDescription input_attributes[32]; + const VkRect2D rt_rect = {.extent = runner->rt_size}; VkPipelineDepthStencilStateCreateInfo ds_desc = {0}; VkVertexInputBindingDescription input_bindings[32]; VkPipelineShaderStageCreateInfo stage_desc[5]; @@ -996,6 +997,8 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn VkImageLayout layout; bool is_ds; + runner->rt_size.width = ~0u; + runner->rt_size.height = ~0u; for (i = 0; i < runner->r.resource_count; ++i) { const struct vulkan_resource *resource = vulkan_resource(runner->r.resources[i]); @@ -1030,6 +1033,11 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn ++color_ref_count; } + if (resource->r.desc.width < runner->rt_size.width) + runner->rt_size.width = resource->r.desc.width; + if (resource->r.desc.height < runner->rt_size.height) + runner->rt_size.height = resource->r.desc.height; + views[view_count++] = resource->image_view; } @@ -1047,8 +1055,8 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn fb_desc.renderPass = *render_pass; fb_desc.attachmentCount = view_count; fb_desc.pAttachments = views; - fb_desc.width = RENDER_TARGET_WIDTH; - fb_desc.height = RENDER_TARGET_HEIGHT; + fb_desc.width = runner->rt_size.width; + fb_desc.height = runner->rt_size.height; fb_desc.layers = 1; VK_CALL(vkCreateFramebuffer(context->device, &fb_desc, NULL, fb)); @@ -1206,8 +1214,6 @@ static bool vulkan_runner_draw(struct shader_runner *r, bool ret = false; unsigned int i; - static const VkRect2D rt_rect = {.extent.width = RENDER_TARGET_WIDTH, .extent.height = RENDER_TARGET_HEIGHT}; - create_render_pass_and_framebuffer(runner, &render_pass, &fb); /* Create this before compiling shaders, it will assign resource bindings. */ @@ -1221,7 +1227,7 @@ static bool vulkan_runner_draw(struct shader_runner *r, pass_begin_desc.renderPass = render_pass; pass_begin_desc.framebuffer = fb; - pass_begin_desc.renderArea = rt_rect; + pass_begin_desc.renderArea.extent = runner->rt_size; VK_CALL(vkCmdBeginRenderPass(cmd_buffer, &pass_begin_desc, VK_SUBPASS_CONTENTS_INLINE));