[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: Re: [vkd3d] Handling object components within the HLSL compiler.
From: Francisco Casas <fcasas () codeweavers ! com>
Date: 2022-08-31 23:52:20
Message-ID: b26800a5-1422-75b9-7383-fa4240f81fa8 () codeweavers ! com
[Download RAW message or body]
On 31-08-22 14:12, Zebediah Figura wrote:
> I don't think I understand the point of splitting uniforms for sm4 but
> not sm1. If we need to determine (and potentially store) the actual type
> of a uniform per-component anyway, why would we need to do that
> differently for structs and arrays?
>
Well, first, I don't think we should split uniforms completely, only
separate the object components as standalone variables.
So, if we have, say
struct {
float4 foo;
Texture2D tex[2];
float4 bar;
} pou;
We would be effectively end up with 3 variables:
The original:
---
struct {
float4 foo;
Texture2D tex[2];
float4 bar;
} pou;
---
and:
---
Texture2D "pou.tex[0]";
Texture2D "pou.tex[1]";
---
because we would be adding a store from the "pou.tex[0]" variable to
pou.tex[0], and from the "pou.tex[1]" variable to pou.tex[1], copy-prop
should replace all derefs to the Texture components to derefs to these
new variables.
The pou variable no longer has to worry about the register allocation of
its Texture fields, because the new variables do that.
Generalizing, variables should no longer care about their object
components, unless they are objects themselves.
I think something similar happens under the hood in SM4, consider the
output of the following shader in the native compiler:
---
struct {
float4 foo;
Texture2D tex[2];
float4 bar;
} pou;
float4 main() : SV_TARGET
{
return pou.bar + pou.tex[0].Load(int3(1, 2, 3)) +
pou.tex[1].Load(int3(1, 2, 3));
}
---
---
// Buffer Definitions:
//
// cbuffer $Globals
// {
//
// struct <unnamed>
// {
//
// float4 foo; // Offset: 0
// float4 bar; // Offset: 16
//
// } pou; // Offset: 0 Size: 32
// Textures: t0-t1
//
// }
//
//
// Resource Bindings:
//
// Name Type Format Dim HLSL Bind Count
// --------------------- ---------- ------- -------- --------- ------
// pou.tex[0] texture float4 2d t0 1
// pou.tex[1] texture float4 2d t1 1
// $Globals cbuffer NA NA cb0 1
---
Object components are listed separately in the resource bindings, and
they are efectively removed (or ignored?) in the definition of pou.
Now, regarding SM1, it is not possible to declare objects inside other
components, it is only possible to create (possibly multi-dimensional)
arrays of single object types:
---
sampler sam[3][2];
float4 main() : SV_TARGET
{
return tex2D(sam[2][1], float2(1, 2));
}
---
but they don't appear as different variables in the CTAB section:
---
// Parameters:
//
// sampler2D sam[6];
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// sam s0 6
//
---
Unlike in SM4:
---
// Resource Bindings:
//
// Name Type Format Dim Slot Elements
// ------------------------ -------- ------- ------ ---- --------
// sam[2][1] sampler NA NA 5 1
// sam[2][1] texture float4 2d 5 1
---
(to get this output I used fxc 9 with compatibility mode)
So, in summary, my idea is to:
- For SM4, separate object components as stand-alone variables that take
care of the register allocation of these individual objects.
- For SM1, just support (possibly multi-dimensional) object arrays.
With this, for both SM1 and SM4, each variable should only care about
the allocation of a single type of register, so we can use the register
offsets as we do now.
In the future we would probably want to remove the "offset" field from
the derefs, and make each hlsl_sm*.c compute the register offsets from
the derefs in their index path form.
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic