diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts index 419e6af93b..197e62aa2d 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts @@ -1,6 +1,7 @@ import { log } from 'app/logging/useLogger'; import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; +import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { ImageDTO, ImageResizeInvocation, @@ -42,9 +43,8 @@ export const buildCanvasImageToImageGraph = ( steps, img2imgStrength: strength, clipSkip, - iterations, - seed, - shouldRandomizeSeed, + shouldUseCpuNoise, + shouldUseNoiseSettings, } = state.generation; // The bounding box determines width and height, not the width and height params @@ -52,6 +52,10 @@ export const buildCanvasImageToImageGraph = ( const model = modelIdToMainModelField(currentModel?.id || ''); + const use_cpu = shouldUseNoiseSettings + ? shouldUseCpuNoise + : initialGenerationState.shouldUseCpuNoise; + /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the * full graph here as a template. Then use the parameters from app state and set friendlier node @@ -78,6 +82,7 @@ export const buildCanvasImageToImageGraph = ( [NOISE]: { type: 'noise', id: NOISE, + use_cpu, }, [MAIN_MODEL_LOADER]: { type: 'main_model_loader', diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts index 70e167aead..918f18a34a 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts @@ -1,5 +1,6 @@ import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; +import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { addControlNetToLinearGraph } from '../addControlNetToLinearGraph'; import { modelIdToMainModelField } from '../modelIdToMainModelField'; import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph'; @@ -30,9 +31,8 @@ export const buildCanvasTextToImageGraph = ( scheduler, steps, clipSkip, - iterations, - seed, - shouldRandomizeSeed, + shouldUseCpuNoise, + shouldUseNoiseSettings, } = state.generation; // The bounding box determines width and height, not the width and height params @@ -40,6 +40,10 @@ export const buildCanvasTextToImageGraph = ( const model = modelIdToMainModelField(currentModel?.id || ''); + const use_cpu = shouldUseNoiseSettings + ? shouldUseCpuNoise + : initialGenerationState.shouldUseCpuNoise; + /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the * full graph here as a template. Then use the parameters from app state and set friendlier node @@ -68,6 +72,7 @@ export const buildCanvasTextToImageGraph = ( id: NOISE, width, height, + use_cpu, }, [TEXT_TO_LATENTS]: { type: 't2l', diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts index 8adf2cf342..f8b95b4d77 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts @@ -1,6 +1,7 @@ import { log } from 'app/logging/useLogger'; import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; +import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { ImageCollectionInvocation, ImageResizeInvocation, @@ -48,6 +49,8 @@ export const buildLinearImageToImageGraph = ( width, height, clipSkip, + shouldUseCpuNoise, + shouldUseNoiseSettings, } = state.generation; const { @@ -75,6 +78,10 @@ export const buildLinearImageToImageGraph = ( const model = modelIdToMainModelField(currentModel?.id || ''); + const use_cpu = shouldUseNoiseSettings + ? shouldUseCpuNoise + : initialGenerationState.shouldUseCpuNoise; + // copy-pasted graph from node editor, filled in with state values & friendly node ids const graph: NonNullableGraph = { id: IMAGE_TO_IMAGE_GRAPH, @@ -102,6 +109,7 @@ export const buildLinearImageToImageGraph = ( [NOISE]: { type: 'noise', id: NOISE, + use_cpu, }, [LATENTS_TO_IMAGE]: { type: 'l2i', diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts index 28ff3656c1..90ddf09343 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts @@ -1,5 +1,6 @@ import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; +import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { addControlNetToLinearGraph } from '../addControlNetToLinearGraph'; import { modelIdToMainModelField } from '../modelIdToMainModelField'; import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph'; @@ -29,10 +30,16 @@ export const buildLinearTextToImageGraph = ( width, height, clipSkip, + shouldUseCpuNoise, + shouldUseNoiseSettings, } = state.generation; const model = modelIdToMainModelField(currentModel?.id || ''); + const use_cpu = shouldUseNoiseSettings + ? shouldUseCpuNoise + : initialGenerationState.shouldUseCpuNoise; + /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the * full graph here as a template. Then use the parameters from app state and set friendlier node @@ -71,6 +78,7 @@ export const buildLinearTextToImageGraph = ( id: NOISE, width, height, + use_cpu, }, [TEXT_TO_LATENTS]: { type: 't2l', diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx new file mode 100644 index 0000000000..5d0ea077c1 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx @@ -0,0 +1,39 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { stateSelector } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAISwitch from 'common/components/IAISwitch'; +import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice'; +import { ChangeEvent } from 'react'; +import { useTranslation } from 'react-i18next'; + +const selector = createSelector( + stateSelector, + (state) => { + const { shouldUseNoiseSettings, shouldUseCpuNoise } = state.generation; + return { + isDisabled: !shouldUseNoiseSettings, + shouldUseCpuNoise, + }; + }, + defaultSelectorOptions +); + +export const ParamCpuNoiseToggle = () => { + const dispatch = useAppDispatch(); + const { isDisabled, shouldUseCpuNoise } = useAppSelector(selector); + + const { t } = useTranslation(); + + const handleChange = (e: ChangeEvent) => + dispatch(shouldUseCpuNoiseChanged(e.target.checked)); + + return ( + + ); +}; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx index 4dea1dad4f..053c1cfec0 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx @@ -7,6 +7,7 @@ import IAICollapse from 'common/components/IAICollapse'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; +import { ParamCpuNoiseToggle } from './ParamCpuNoise'; import ParamNoiseThreshold from './ParamNoiseThreshold'; import { ParamNoiseToggle } from './ParamNoiseToggle'; import ParamPerlinNoise from './ParamPerlinNoise'; @@ -40,6 +41,7 @@ const ParamNoiseCollapse = () => { > + diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 79372914b4..867eb6ed07 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -55,6 +55,7 @@ export interface GenerationState { seamlessXAxis: boolean; seamlessYAxis: boolean; clipSkip: number; + shouldUseCpuNoise: boolean; } export const initialGenerationState: GenerationState = { @@ -90,6 +91,7 @@ export const initialGenerationState: GenerationState = { seamlessXAxis: false, seamlessYAxis: false, clipSkip: 0, + shouldUseCpuNoise: true, }; const initialState: GenerationState = initialGenerationState; @@ -239,6 +241,9 @@ export const generationSlice = createSlice({ setClipSkip: (state, action: PayloadAction) => { state.clipSkip = action.payload; }, + shouldUseCpuNoiseChanged: (state, action: PayloadAction) => { + state.shouldUseCpuNoise = action.payload; + }, }, extraReducers: (builder) => { builder.addCase(configChanged, (state, action) => { @@ -298,6 +303,7 @@ export const { setSeamlessXAxis, setSeamlessYAxis, setClipSkip, + shouldUseCpuNoiseChanged, } = generationSlice.actions; export default generationSlice.reducer;