From d6a37a0f151e390808f196998c48a341bc4c7b60 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 12 Mar 2021 11:58:14 -0800 Subject: Add a CPU renderer implementation (#1750) * Add a CPU renderer implementation This change adds a CPU back-end to `gfx` and ensures that most of our existing CPU tests pass when using it. Detailed notes: * Most of the CPU renderer implementation is copy-pasted from the CUDA case, so they share a lot of similar logic * The main addition to the CPU renderer is a semi-complete implementation of host-memory textures. The logic here handles all the main shapes (Buffer, 1D, 2D, 3D, Cube) and all the currently-supported `Format`s that are sample-able as-is (no D24S8). The implementation is not intended to be fast, and it currently only does nearest-neighbor sampling, but otherwise it tries to avoid cutting too many corners and should be ar reasonable starting point for a more complete (but not performance-oriented) implementation. * Refactored the CPU prelude `IRWTexture` interface to inherit from `ITexture`, since in most cases a single type will end up implementing both. It might be worth it to collapse it all down to a single interface later. * Changed the CPU prelude `ITexture`/`IRWTexture` interface so that it takes both a pointer *and* a size for output arguments. This change seems necessary to allow a shader variable declared as a `Texture2D` to fetch a single `float` when the underlying texture might be using RGBA32F. * Added to the `IComponentType` public API so that we can query a "host callable" for an entry point and not just a binary. * Turned off the `-shaderobj` flag on two tests that weren't yet compatible with shader objects but still had the flag left in on the path (since previously the CPU path always used the non-`gfx` non-shader-object logic anyway) * Disabled one test (`dynamic-dispatch-11`) that relied on the `ConstantBuffer` idiom that we know we are planning to chagne soon anyway. * Made a few changes to the CUDA path to bring it into line with what I added for the CPU path. These were mostly bug fixes around indexing logic for sub-objects and resources. * fixup --- prelude/slang-cpp-types.h | 60 ++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) (limited to 'prelude') diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h index 9c8fb3dec..99e8f5097 100644 --- a/prelude/slang-cpp-types.h +++ b/prelude/slang-cpp-types.h @@ -446,9 +446,9 @@ struct TextureDimensions struct ITexture { virtual TextureDimensions GetDimensions(int mipLevel = -1) = 0; - virtual void Load(const int* v, void* out) = 0; - virtual void Sample(SamplerState samplerState, const float* loc, void* out) = 0; - virtual void SampleLevel(SamplerState samplerState, const float* loc, float level, void* out) = 0; + virtual void Load(const int32_t* v, void* outData, size_t dataSize) = 0; + virtual void Sample(SamplerState samplerState, const float* loc, void* outData, size_t dataSize) = 0; + virtual void SampleLevel(SamplerState samplerState, const float* loc, float level, void* outData, size_t dataSize) = 0; }; template @@ -470,9 +470,9 @@ struct Texture1D *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } - T Sample(SamplerState samplerState, float loc) const { T out; texture->Sample(samplerState, &loc, &out); return out; } - T SampleLevel(SamplerState samplerState, float loc, float level) { T out; texture->SampleLevel(samplerState, &loc, level, &out); return out; } + T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } + T Sample(SamplerState samplerState, float loc) const { T out; texture->Sample(samplerState, &loc, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, float loc, float level) { T out; texture->SampleLevel(samplerState, &loc, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -507,9 +507,9 @@ struct Texture2D *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } - T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } + T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -548,9 +548,9 @@ struct Texture3D *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } - T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } + T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -585,8 +585,8 @@ struct TextureCube *outNumberOfLevels = dims.numberOfLevels; } - T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -611,9 +611,9 @@ struct Texture1DArray *outElements = dims.arrayElementCount; } - T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } - T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } + T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -653,9 +653,9 @@ struct Texture2DArray *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } - T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } + T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; @@ -695,20 +695,16 @@ struct TextureCubeArray *outNumberOfLevels = dims.numberOfLevels; } - T Sample(SamplerState samplerState, const float4& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } - T SampleLevel(SamplerState samplerState, const float4& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } + T Sample(SamplerState samplerState, const float4& loc) const { T out; texture->Sample(samplerState, &loc.x, &out, sizeof(out)); return out; } + T SampleLevel(SamplerState samplerState, const float4& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out, sizeof(out)); return out; } ITexture* texture; }; /* !!!!!!!!!!!!!!!!!!!!!!!!!!! RWTexture !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -struct IRWTexture +struct IRWTexture : ITexture { - virtual TextureDimensions GetDimensions(int mipLevel = -1) = 0; - - /// Load at specified location. - virtual void Load(const int32_t* loc, void* out) = 0; /// Get the reference to the element at loc. virtual void* refAt(const uint32_t* loc) = 0; }; @@ -722,7 +718,7 @@ struct RWTexture1D void GetDimensions(float* outWidth) { *outWidth = texture->GetDimensions().width; } void GetDimensions(uint32_t mipLevel, float* outWidth, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); *outWidth = dims.width; *outNumberOfLevels = dims.numberOfLevels; } - T Load(int32_t loc) const { T out; texture->Load(&loc, &out); return out; } + T Load(int32_t loc) const { T out; texture->Load(&loc, &out, sizeof(out)); return out; } T& operator[](uint32_t loc) { return *(T*)texture->refAt(&loc); } IRWTexture* texture; }; @@ -757,7 +753,7 @@ struct RWTexture2D *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } + T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } T& operator[](const uint2& loc) { return *(T*)texture->refAt(&loc.x); } IRWTexture* texture; }; @@ -796,7 +792,7 @@ struct RWTexture3D *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } + T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } T& operator[](const uint3& loc) { return *(T*)texture->refAt(&loc.x); } IRWTexture* texture; }; @@ -832,7 +828,7 @@ struct RWTexture1DArray *outNumberOfLevels = dims.numberOfLevels; } - T Load(int2 loc) const { T out; texture->Load(&loc.x, &out); return out; } + T Load(int2 loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } T& operator[](uint2 loc) { return *(T*)texture->refAt(&loc.x); } IRWTexture* texture; @@ -872,7 +868,7 @@ struct RWTexture2DArray *outNumberOfLevels = dims.numberOfLevels; } - T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } + T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out, sizeof(out)); return out; } T& operator[](const uint3& loc) { return *(T*)texture->refAt(&loc.x); } IRWTexture* texture; -- cgit v1.2.3